successivo
precedente
inizio
fine
indice generale
aiuto
indice analitico
volume
parte
TXT
HTML
PDF
pdf
gdoc
P4
Capitolo 94. Script e sorgenti del kernel
94.1
os32: directory principale
94.1.1
applic.sep.ld
Si veda la sezione 84.1.3.
10001 /*****************************************************
10002 * SEPARATED text from data
10003 *****************************************************/
10004
10005 ENTRY (startup)
10006 SECTIONS {
10007 . = 0x0;
10008 _text_start = .;
10009 .text : {
10010 *(.text)
10011 . = ALIGN (0x4);
10012 }
10013 _text_end = .;
10014 . = 0x0;
10015 _data_start = .;
10016 .rodata : {
10017 *(.rodata)
10018 . = ALIGN (0x4);
10019 }
10020 .data : {
10021 *(.data)
10022 . = ALIGN (0x4);
10023 }
10024 _data_end = .;
10025 _bss_start = .;
10026 .bss : {
10027 *(COMMON)
10028 *(.bss)
10029 . = ALIGN (0x4);
10030 }
10031 _bss_end = .;
10032 }
|
|
94.1.2
bochs
Si veda la sezione 85.4.
20001 #!/bin/sh
20002
20003 if [ "$UID" = 0 ]
20004 then
20005 # 172.21.11.18 172.21.11.16
20006 # >-----------point to point -----> >-------os32
20007 # tap0 (linux) net1
20008 #
20009 # Dal lato Linux:
20010 # ifconfig tap0 172.21.11.18 pointopoint \
20011 # 172.21.11.16 netmask 255.255.255.255
20012 # route add -host 172.21.11.16 gw 172.21.11.18
20013 #
20014 # Dalla macchina 172.21.254.254:
20015 # route add -host 172.21.11.16 gw 172.21.11.18
20016 #
20017 bochs -q \
20018 "boot: disk" \
20019 "ata0-master: type=disk, path=disk.hda" \
20020 "keyboard_mapping: enabled=1, \
20021 map=/usr/share/bochs/keymaps/x11-pc-it.map" \
20022 "keyboard_type: mf" \
20023 "vga: none" \
20024 "ne2k: mac=b0:c4:20:00:00:00, ioaddr=0x300, \
20025 irq=9, ethmod=tuntap, ethdev=/dev/net/tun, \
20026 script=./tap0" \
20027 "i440fxsupport: enabled=1, slot1=pcivga, \
20028 slot2=ne2k" \
20029 "romimage: \
20030 file=\"/usr/share/bochs/BIOS-bochs-legacy\"" \
20031 "megs:128"
20032 else
20033 bochs -q \
20034 "boot: disk" \
20035 "ata0-master: type=disk, path=disk.hda" \
20036 "keyboard_mapping: enabled=1, \
20037 map=/usr/share/bochs/keymaps/x11-pc-it.map" \
20038 "keyboard_type: mf" \
20039 "vga: none" \
20040 "ne2k: mac=b0:c4:20:00:00:00, ioaddr=0x300, \
20041 irq=9, ethmod=null" \
20042 "i440fxsupport: enabled=1, slot1=pcivga, \
20043 slot2=ne2k" \
20044 "romimage: \
20045 file=\"/usr/share/bochs/BIOS-bochs-legacy\"" \
20046 "megs:128"
20047 fi
|
|
94.1.3
elf-to-os32
Si veda la sezione 84.1.3.
30001 #!/bin/sh
30002 #
30003 #
30004 #
30005 g_sz ()
30006 {
30007 sed "s/^[[:space:]]*[0-9]*[[:space:]]*//" \
30008 | sed "s/\.[^[:space:]]*[[:space:]]*//" \
30009 | sed "s/\([0-9a-z]*\)[[:space:]].*$/\1/"
30010 }
30011 #
30012 g_vma ()
30013 {
30014 sed "s/^[[:space:]]*[0-9]*[[:space:]]*//" \
30015 | sed "s/\.[^[:space:]]*[[:space:]]*//" \
30016 | sed "s/[0-9a-f]*[[:space:]]*//" \
30017 | sed "s/\([0-9a-z]*\)[[:space:]].*$/\1/"
30018 }
30019 #
30020 g_st ()
30021 {
30022 sed "s/^[[:space:]]*[0-9]*[[:space:]]*//" \
30023 | sed "s/\.[^[:space:]]*[[:space:]]*//" \
30024 | sed "s/[0-9a-f]*[[:space:]]*//" \
30025 | sed "s/[0-9a-f]*[[:space:]]*//" \
30026 | sed "s/[0-9a-f]*[[:space:]]*//" \
30027 | sed "s/\([0-9a-z]*\)[[:space:]].*$/\1/"
30028 }
30029 #
30030 FILE_ELF="$1"
30031 FILE_OS32="$2"
30032 #
30033 if [ -e "$FILE_ELF" ]
30034 then
30035 true
30036 else
30037 exit
30038 fi
30039 #
30040 T_ST=`objdump -h $FILE_ELF | grep -F ".text" | g_st`
30041 T_VM=`objdump -h $FILE_ELF | grep -F ".text" | g_vma`
30042 T_SZ=`objdump -h $FILE_ELF | grep -F ".text" | g_sz`
30043 #
30044 R_ST=`objdump -h $FILE_ELF | grep -F ".rodata" | g_st`
30045 R_VM=`objdump -h $FILE_ELF | grep -F ".rodata" | g_vma`
30046 R_SZ=`objdump -h $FILE_ELF | grep -F ".rodata" | g_sz`
30047 #
30048 D_ST=`objdump -h $FILE_ELF | grep -F ".data" | g_st`
30049 D_VM=`objdump -h $FILE_ELF | grep -F ".data" | g_vma`
30050 D_SZ=`objdump -h $FILE_ELF | grep -F ".data" | g_sz`
30051 #
30052 # Convert to decimal
30053 #
30054 T_ST=`printf "%i" 0x$T_ST`
30055 T_VM=`printf "%i" 0x$T_VM`
30056 T_SZ=`printf "%i" 0x$T_SZ`
30057 #
30058 R_ST=`printf "%i" 0x$R_ST`
30059 R_VM=`printf "%i" 0x$R_VM`
30060 R_SZ=`printf "%i" 0x$R_SZ`
30061 #
30062 D_ST=`printf "%i" 0x$D_ST`
30063 D_VM=`printf "%i" 0x$D_VM`
30064 D_SZ=`printf "%i" 0x$D_SZ`
30065
30066
30067 if [ "$R_SZ" = "$D_VM" ]
30068 then
30069 dd if=$FILE_ELF of=$FILE_OS32.text \
30070 bs=1 skip=$T_ST count=$T_SZ 2> "/dev/null"
30071 dd if=$FILE_ELF of=$FILE_OS32.rodata \
30072 bs=1 skip=$R_ST count=$R_SZ 2> "/dev/null"
30073 dd if=$FILE_ELF of=$FILE_OS32.data \
30074 bs=1 skip=$D_ST count=$D_SZ 2> "/dev/null"
30075 cat $FILE_OS32.text $FILE_OS32.rodata \
30076 $FILE_OS32.data > $FILE_OS32
30077 #
30078 #rm $FILE_OS32.text
30079 #rm $FILE_OS32.rodata
30080 #rm $FILE_OS32.data
30081 #
30082 chmod a+x $FILE_OS32
30083 elif [ "$R_SZ" -lt "$D_VM" ]
30084 then
30085 dd if=$FILE_ELF of=$FILE_OS32.text \
30086 bs=1 skip=$T_ST count=$T_SZ 2> "/dev/null"
30087 dd if=$FILE_ELF of=$FILE_OS32.rodata \
30088 bs=1 skip=$R_ST count=$R_SZ 2> "/dev/null"
30089 dd if=/dev/zero of=$FILE_OS32.rodata-space \
30090 bs=1 count=$(($D_VM-$R_SZ)) 2> "/dev/null"
30091 dd if=$FILE_ELF of=$FILE_OS32.data \
30092 bs=1 skip=$D_ST count=$D_SZ 2> "/dev/null"
30093
30094 cat $FILE_OS32.text \
30095 $FILE_OS32.rodata \
30096 $FILE_OS32.rodata-space \
30097 $FILE_OS32.data > $FILE_OS32
30098 #
30099 #rm $FILE_OS32.text
30100 #rm $FILE_OS32.rodata
30101 #rm $FILE_OS32.rodata-space
30102 #rm $FILE_OS32.data
30103 #
30104 chmod a+x $FILE_OS32
30105 else
30106 echo "[$0] ERROR: $FILE_ELF has DATA section"
30107 echo "[$0] not contiguous:"
30108 echo "[$0] RODATA end at $R_SZ, and DATA"
30109 echo "[$0] should start at $D_VM!"
30110 fi
|
|
94.1.4
fdisk
Si veda la sezione 85.1.
40001 #!/bin/sh
40002 #
40003 #
40004 #
40005 . ./file_image_functions
40006 #
40007 if [ -z "$1" ]
40008 then
40009 echo "$0 DISK_IMAGE_FILE"
40010 else
40011 file_image_fdisk "$1"
40012 fi
40013 #
|
|
94.1.5
file_image_functions
Si veda la sezione 85.1.
50001 #
50002 # file_image_fdisk IMAGE_FILE
50003 #
50004 file_image_fdisk () {
50005 #
50006 local FNAME="$1"
50007 local FSIZE=0
50008 local CYLINDERS=0
50009 local HEADS=0
50010 local SECTORS=63
50011 #
50012 if [ -z "$FNAME" ]
50013 then
50014 echo "[$0] No file name."
50015 return 1
50016 elif [ ! -r "$FNAME" ]
50017 then
50018 echo "[$0] Cannot read file \"$FNAME\"."
50019 return 1
50020 fi
50021 #
50022 # Get size
50023 #
50024 FSIZE=`du -k "$FNAME" | sed "s/[[:space:]].*$//"`
50025 #
50026 # Set geometry
50027 #
50028 if [ "$FSIZE" -le "516096" ]
50029 then
50030 HEADS="16"
50031 else
50032 HEADS="255"
50033 fi
50034 #
50035 CYLINDERS=$(($FSIZE*2/$SECTORS/$HEADS))
50036 #
50037 # Run fdisk.
50038 #
50039 fdisk -C $CYLINDERS -H $HEADS -S $SECTORS $FNAME
50040 }
50041 #
50042 # file_image_partition_start IMAGE_FILE PART_NUMBER
50043 #
50044 file_image_partition_start () {
50045 #
50046 local FNAME="$1"
50047 local PART_NUMBER="$2"
50048 local PART_START=0
50049 #
50050 # Get partition start
50051 #
50052 PART_START=`sfdisk -d $FNAME \
50053 | grep -F "$FNAME$PART_NUMBER" \
50054 | sed "s/^.*start=[[:space:]]*//" | sed "s/,.*$//"`
50055 #
50056 echo "$PART_START"
50057 }
50058 #
50059 # file_image_partition_size IMAGE_FILE PART_NUMBER
50060 #
50061 file_image_partition_size () {
50062 #
50063 local FNAME="$1"
50064 local PART_NUMBER="$2"
50065 local PART_SIZE=0
50066 #
50067 # Get partition start
50068 #
50069 PART_SIZE=`sfdisk -d $FNAME \
50070 | grep -F "$FNAME$PART_NUMBER" \
50071 | sed "s/^.*size=[[:space:]]*//" | sed "s/,.*$//"`
50072 #
50073 echo "$PART_SIZE"
50074 }
50075 #
50076 # file_image_partition_id IMAGE_FILE PART_NUMBER
50077 #
50078 file_image_partition_id () {
50079 #
50080 local FNAME="$1"
50081 local PART_NUMBER="$2"
50082 local PART_ID=0
50083 #
50084 # Get partition start
50085 #
50086 PART_ID=`sfdisk -d $FNAME \
50087 | grep -F "$FNAME$PART_NUMBER" \
50088 | sed "s/^.*Id=[[:space:]]*//" | sed "s/,.*$//"`
50089 #
50090 echo "$PART_ID"
50091 }
50092 #
50093 # file_image_partition_format IMAGE_FILE PART_NUMBER \
50094 # [dos|minix]
50095 #
50096 file_image_partition_format () {
50097 #
50098 local FNAME="$1"
50099 local PART_NUMBER="$2"
50100 local PART_FORMAT="$3"
50101 local PART_START=`file_image_partition_start \
50102 $FNAME $PART_NUMBER`
50103 local PART_SIZE=`file_image_partition_size $FNAME \
50104 $PART_NUMBER`
50105 local PART_ID=`file_image_partition_id $FNAME \
50106 $PART_NUMBER`
50107 #
50108 #
50109 #
50110 if [ "$PART_SIZE" -eq "0" ]
50111 then
50112 exit
50113 fi
50114 #
50115 # Get partition into a file.
50116 #
50117 dd if="$FNAME" \
50118 of="$FNAME.part$PART_NUMBER.tmp" \
50119 bs=512 \
50120 skip="$PART_START" \
50121 count="$PART_SIZE"
50122 #
50123 # Format.
50124 #
50125 if [ "$PART_FORMAT" = "dos" ] \
50126 || [ "$PART_FORMAT" = "msdos" ]
50127 then
50128 mkfs.msdos -v "$FNAME.part$PART_NUMBER.tmp"
50129 else
50130 mkfs.minix -n 14 "$FNAME.part$PART_NUMBER.tmp"
50131 fi
50132 #
50133 # Put formatted partition into the file.
50134 #
50135 dd if="$FNAME.part$PART_NUMBER.tmp" \
50136 of="$FNAME" \
50137 bs=512 \
50138 seek="$PART_START" \
50139 count="$PART_SIZE" \
50140 conv=notrunc
50141 #
50142 # Remove temporary file.
50143 #
50144 rm "$FNAME.part$PART_NUMBER.tmp"
50145 #
50146 }
50147 #
50148 # file_image_partition_mount IMAGE_FILE PART_NUMBER
50149 #
50150 file_image_partition_mount () {
50151 #
50152 local FNAME="$1"
50153 local PART_NUMBER="$2"
50154 local PART_START=`file_image_partition_start \
50155 $FNAME $PART_NUMBER`
50156 local PART_SIZE=`file_image_partition_size \
50157 $FNAME $PART_NUMBER`
50158 local PART_ID=`file_image_partition_id \
50159 $FNAME $PART_NUMBER`
50160 local MOUNT_POINT
50161 #
50162 #
50163 #
50164 if [ "$PART_SIZE" -eq "0" ]
50165 then
50166 exit
50167 fi
50168 #
50169 # Find mount point.
50170 #
50171 MOUNT_POINT=`basename $FNAME`
50172 MOUNT_POINT="/mnt/${MOUNT_POINT}.$PART_NUMBER"
50173 #
50174 #
50175 #
50176 sync
50177 #
50178 umount "$MOUNT_POINT" 2> "/dev/null"
50179 umount "$MOUNT_POINT" 2> "/dev/null"
50180 umount "$MOUNT_POINT" 2> "/dev/null"
50181 #
50182 mkdir -p "$MOUNT_POINT" 2> "/dev/null"
50183 #
50184 # Get partition into a file.
50185 #
50186 dd if="$FNAME" \
50187 of="$FNAME.part$PART_NUMBER.tmp" \
50188 bs=512 \
50189 skip="$PART_START" \
50190 count="$PART_SIZE"
50191 #
50192 # Check partition.
50193 #
50194 fsck -f -v -r "$FNAME.part$PART_NUMBER.tmp"
50195 #
50196 # Put formatted partition into the file.
50197 #
50198 dd if="$FNAME.part$PART_NUMBER.tmp" \
50199 of="$FNAME" \
50200 bs=512 \
50201 seek="$PART_START" \
50202 count="$PART_SIZE" \
50203 conv=notrunc
50204 #
50205 # Remove temporary file.
50206 #
50207 rm "$FNAME.part$PART_NUMBER.tmp"
50208 #
50209 # Mount the partition.
50210 #
50211 mount -o loop,offset=$(($PART_START*512)) \
50212 -t auto "$FNAME" "$MOUNT_POINT"
50213 #
50214 }
50215 #
50216 # file_image_partition_syslinux IMAGE_FILE PART_NUMBER
50217 #
50218 file_image_partition_syslinux () {
50219 #
50220 local FNAME="$1"
50221 local PART_NUMBER="$2"
50222 local PART_START=`file_image_partition_start \
50223 $FNAME $PART_NUMBER`
50224 local PART_SIZE=`file_image_partition_size \
50225 $FNAME $PART_NUMBER`
50226 local PART_ID=`file_image_partition_id \
50227 $FNAME $PART_NUMBER`
50228 #
50229 #
50230 #
50231 if [ "$PART_SIZE" -eq "0" ]
50232 then
50233 exit
50234 fi
50235 #
50236 # Get partition into a file.
50237 #
50238 dd if="$FNAME" \
50239 of="$FNAME.part$PART_NUMBER.tmp" \
50240 bs=512 \
50241 skip="$PART_START" \
50242 count="$PART_SIZE"
50243 #
50244 # Syslinux
50245 #
50246 syslinux "$FNAME.part$PART_NUMBER.tmp"
50247 #
50248 # Put altered partition into the file.
50249 #
50250 dd if="$FNAME.part$PART_NUMBER.tmp" \
50251 of="$FNAME" \
50252 bs=512 \
50253 seek="$PART_START" \
50254 count="$PART_SIZE" \
50255 conv=notrunc
50256 #
50257 # Remove temporary file.
50258 #
50259 rm "$FNAME.part$PART_NUMBER.tmp"
50260 #
50261 # Fix MBR
50262 #
50263 install-mbr $FNAME
50264 }
50265
|
|
94.1.6
format
Si veda la sezione 85.1.
60001 #!/bin/sh
60002 #
60003 #
60004 #
60005 . ./file_image_functions
60006 #
60007 if [ -z "$1" ] \
60008 || [ -z "$2" ] \
60009 || [ "$2" -lt "1" ] \
60010 || [ "$2" -gt "4" ]
60011 then
60012 echo "Usage:"
60013 echo ""
60014 echo "$0 DISK_IMAGE_FILE PART_NUMBER dos|minix"
60015 echo ""
60016 echo "The partition number must be between"
60017 echo " 1 and 4. No extended partitions are"
60018 echo "handled!"
60019 else
60020 file_image_partition_format "$1" "$2" "$3"
60021 fi
60022 #
|
|
94.1.7
kernel.ld
Si veda la sezione 84.2.2.
70001 /*****************************************************
70002 * The code will start at address 0x100000, that is at
70003 * 1 Mibyte, because it is the place where GRUB will
70004 * place it.
70005 *
70006 * The kernel is divided into `TEXT' (code), `DATA' and
70007 * `BSS'.
70008 * Between the TEXT and the DATA there is a gap to
70009 * align the data at 4 Kibyte boundary (0x1000), to
70010 * allow memory management for it.
70011 *
70012 * The stack will be placed at the beginning of the
70013 * BSS.
70014 *
70015 * The kernel starts with file `kernel/main/crt0.s',
70016 * at the label `startup'.
70017 *****************************************************/
70018 ENTRY (kstartup)
70019 SECTIONS {
70020 . = 0x00100000;
70021 _k_start = .;
70022 _k_text_start = .;
70023 .text : {
70024 *(.text)
70025 }
70026 _k_text_end = .;
70027 . = ALIGN (0x1000);
70028 _k_data_start = .;
70029 .rodata : {
70030 *(.rodata)
70031 }
70032 . = ALIGN (0x4);
70033 .data : {
70034 *(.data)
70035 }
70036 _k_data_end = .;
70037 . = ALIGN (0x4);
70038 _k_bss_start = .;
70039 .bss : {
70040 *(COMMON)
70041 *(.bss)
70042 }
70043 _k_bss_end = .;
70044 _k_end = .;
70045 }
|
|
94.1.8
makeit.sep
Si veda la sezione 91.3.
80001 #!/bin/sh
80002 #
80003 # makeit... separated: text and data have separate
80004 # segments.
80005 #
80006 OPTION="$1"
80007 OS32PATH=""
80008 #
80009 #
80010 #
80011 edition () {
80012 local EDITION="kernel/main/build.h"
80013 echo -n > $EDITION
80014 echo -n "#define BUILD_DATE \"" >> $EDITION
80015 echo -n `date "+%Y%m%d%H%M"` >> $EDITION
80016 echo "\"" >> $EDITION
80017 }
80018 #
80019 #
80020 #
80021 makefile () {
80022 #
80023 local MAKEFILE="Makefile"
80024 local TAB=`printf "\t"`
80025 #
80026 local SOURCE_C=""
80027 local C=""
80028 local SOURCE_S=""
80029 local S=""
80030 #
80031 local c
80032 local s
80033 #
80034 # Find C source files.
80035 #
80036 for c in *.c
80037 do
80038 if [ -f $c ]
80039 then
80040 C=`basename $c .c`
80041 SOURCE_C="$SOURCE_C $C"
80042 fi
80043 done
80044 #
80045 # Find ASM source files.
80046 #
80047 for s in *.s
80048 do
80049 if [ -f $s ]
80050 then
80051 S=`basename $s .s`
80052 SOURCE_S="$SOURCE_S $S"
80053 fi
80054 done
80055 #
80056 # Prepare the Makefile. Option `-g' is for debugging
80057 # symbols.
80058 #
80059 echo -n > $MAKEFILE
80060 echo "# This file was made " >> $MAKEFILE
80061 echo "# automatically" >> $MAKEFILE
80062 echo "# by the script \`makeit', based" >> $MAKEFILE
80063 echo "# on the directory content." >> $MAKEFILE
80064 echo "# Please use \`makeit' to " >> $MAKEFILE
80065 echo "# compile and" >> $MAKEFILE
80066 echo "# \`makeit clean\' to clean " >> $MAKEFILE
80067 echo "# directories." >> $MAKEFILE
80068 echo "#" >> $MAKEFILE
80069 echo "#" >> $MAKEFILE
80070 echo "c = $SOURCE_C" >> $MAKEFILE
80071 echo "#" >> $MAKEFILE
80072 echo "s = $SOURCE_S" >> $MAKEFILE
80073 echo "#" >> $MAKEFILE
80074 echo "all: \$(s) \$(c)" >> $MAKEFILE
80075 echo "#" >> $MAKEFILE
80076 echo "clean:" >> $MAKEFILE
80077 echo "${TAB}@rm *~ *.o *.ELF *.text " \
80078 "*.rodata *.rodata-space " \
80079 "*.data \$(c) 2> /dev/null ; pwd" >> $MAKEFILE
80080 echo "#" >> $MAKEFILE
80081 echo "\$(s):" >> $MAKEFILE
80082 echo "${TAB}@echo \$@.s" >> $MAKEFILE
80083 echo "${TAB}@as -o \$@.o \$@.s" >> $MAKEFILE
80084 echo "#" >> $MAKEFILE
80085 echo "\$(c):" >> $MAKEFILE
80086 echo "${TAB}@echo \$@.c" >> $MAKEFILE
80087 echo "${TAB}@gcc -O0 -Wall -Werror " \
80088 "-Wno-unused-but-set-variable" \
80089 "-g" \
80090 "-o \$@.o -c \$@.c" \
80091 "-nostdinc -nostdlib " \
80092 "-nostartfiles -nodefaultlibs" \
80093 "-I " \
80094 "-I. " \
80095 "-I$OS32PATH/lib " \
80096 "-I$OS32PATH/ " \
80097 "-I../include -I../../include " \
80098 "-I../../../include" >> $MAKEFILE
80099 #
80100 }
80101 #
80102 #
80103 #
80104 main () {
80105 #
80106 local CURDIR=`pwd`
80107 local OBJECTS
80108 local d
80109 local c
80110 local s
80111 local o
80112 #
80113 edition
80114 #
80115 # Copia dello scheletro
80116 #
80117 if [ "$OPTION" = "clean" ]
80118 then
80119 #
80120 # La copia non va fatta.
80121 #
80122 true
80123 else
80124 cp -dpRv skel/etc /mnt/disk.hda.2/
80125 cp -dpRv skel/dev /mnt/disk.hda.2/
80126 mkdir /mnt/disk.hda.2/mnt/
80127 mkdir /mnt/disk.hda.2/tmp/
80128 chmod 0777 /mnt/disk.hda.2/tmp/
80129 mkdir /mnt/disk.hda.2/usr/
80130 mkdir /mnt/disk.hda.2/var/
80131 cp -dpRv skel/root /mnt/disk.hda.2/
80132 cp -dpRv skel/home /mnt/disk.hda.2/
80133 cp -dpRv skel/usr/* /mnt/disk.hda.2/usr/
80134 cp -dpRv skel/var/* /mnt/disk.hda.2/var/
80135 fi
80136 #
80137 for d in `find .`
80138 do
80139 if [ -d "$d" ]
80140 then
80141 #
80142 # Are there C or ASM source files?
80143 #
80144 c=`echo $d/*.c | sed "s/ .*//"`
80145 s=`echo $d/*.s | sed "s/ .*//"`
80146 #
80147 if [ -f "$c" ] || [ -f "$s" ]
80148 then
80149 CURDIR=`pwd`
80150 cd $d
80151 #
80152 # Build the new makefile
80153 #
80154 makefile
80155 #
80156 # Clean the directory
80157 #
80158 make clean
80159 #
80160 #
80161 #
80162 if [ "$OPTION" = "clean" ]
80163 then
80164 #
80165 # Nothing else to do: the clean was
80166 # just made.
80167 #
80168 true
80169 else
80170 if ! make
80171 then
80172 cd "$CURDIR"
80173 exit
80174 fi
80175 fi
80176 cd "$CURDIR"
80177 fi
80178 fi
80179 done
80180 #
80181 cd "$CURDIR"
80182 #
80183 #
80184 #
80185 if [ "$OPTION" = "clean" ]
80186 then
80187 true
80188 else
80189 #
80190 echo "Link kernel"
80191 #
80192 OBJECTS=""
80193 #
80194 for o in `find . -name \*.o -print`
80195 do
80196 if [ "$o" = "./kernel/main/crt0.o" ] \
80197 || [ "$o" = "./kernel/main/kmain.o" ] \
80198 || [ "$o" = "./kernel/main/stack.o" ] \
80199 || [ ! -e "$o" ] \
80200 || echo "$o" | grep -F "./applic/" \
80201 > "/dev/null" \
80202 || echo "$o" | grep -F "./ported/" \
80203 > "/dev/null"
80204 then
80205 true
80206 else
80207 OBJECTS="$OBJECTS $o"
80208 fi
80209 done
80210 #
80211 # The kernel must be ELF, because Grub will not
80212 # recognize it otherwise.
80213 #
80214 ld --script=kernel.ld \
80215 --oformat elf32-i386 \
80216 -o kimage \
80217 ./kernel/main/crt0.o \
80218 $OBJECTS \
80219 ./kernel/main/kmain.o \
80220 ./kernel/main/stack.o
80221 #
80222 cp -f kimage /mnt/disk.hda.1/kimage
80223 sync
80224 #
80225 # Collegamento delle applicazioni di os32.
80226 #
80227 OBJLIB=""
80228 #
80229 for o in `find lib -name \*.o -print`
80230 do
80231 OBJLIB="$OBJLIB $o"
80232 done
80233 #
80234 echo "Link applic"
80235 #
80236 # Scansione delle applicazioni interne.
80237 #
80238 for o in `find applic -name \*.o -print`
80239 do
80240 if [ "$o" = "applic/crt0.o" ] \
80241 || [ ! -e "$o" ] \
80242 || echo "$o" | grep ".crt0.o$" > /dev/null \
80243 || echo "$o" | grep ".crt0.mer.o$" \
80244 > /dev/null \
80245 || echo "$o" | grep ".crt0.sep.o$" > /dev/null
80246 then
80247 #
80248 # Il file non esiste oppure si tratta di
80249 # `...crt0.s'.
80250 #
80251 true
80252 else
80253 #
80254 # File oggetto differente da `...crt0.s'.
80255 #
80256 EXEC=`echo "$o" | sed "s/\.o$//"`
80257 BASENAME=`basename $o .o`
80258 if [ -e "applic/$BASENAME.crt0.sep.o" ]
80259 then
80260 #
80261 # Qui c'è un file `...crt0.o' specifico.
80262 #
80263 rm $EXEC $EXEC.ELF 2> "/dev/null"
80264 ld --no-check-sections \
80265 --oformat elf32-i386 \
80266 --script=applic.sep.ld \
80267 -o $EXEC.ELF \
80268 ./applic/$BASENAME.crt0.sep.o \
80269 $o \
80270 $OBJLIB
80271 #
80272 ./elf-to-os32 $EXEC.ELF $EXEC
80273 else
80274 #
80275 # Qui si usa il file `crt0.sep.o' generale.
80276 #
80277 rm $EXEC $EXEC.ELF 2> "/dev/null"
80278 ld --script=applic.sep.ld \
80279 --no-check-sections \
80280 --oformat elf32-i386 \
80281 -o $EXEC.ELF \
80282 ./applic/crt0.sep.o \
80283 $o \
80284 $OBJLIB
80285 #
80286 ./elf-to-os32 $EXEC.ELF $EXEC
80287 fi
80288 #
80289 if [ -x "applic/$BASENAME" ]
80290 then
80291 if mount | grep /mnt/disk.hda.2 > /dev/null
80292 then
80293 mkdir /mnt/disk.hda.2/bin/ 2> /dev/null
80294 rm /mnt/disk.hda.2/bin/$EXEC 2> "/dev/null"
80295 cp -f "$EXEC" /mnt/disk.hda.2/bin
80296 else
80297 echo "[$0] Cannot copy the application"
80298 echo "[$0] $BASENAME inside the disk"
80299 echo "[$0] image!"
80300 break
80301 fi
80302 fi
80303 fi
80304 done
80305 sync
80306 #
80307 echo "Link ported"
80308 #
80309 # Scansione delle applicazioni adattate.
80310 #
80311 for a in ported/*
80312 do
80313 if [ -d $a ]
80314 then
80315 OBJECTS=""
80316 for o in `find $a -name \*.o -print`
80317 do
80318 if [ "$o" = "$a/crt0.o" ] \
80319 || [ ! -e "$o" ] \
80320 || echo "$o" | grep "crt0.o$" > /dev/null \
80321 || echo "$o" | grep "crt0.mer.o$" \
80322 > /dev/null \
80323 || echo "$o" | grep "crt0.sep.o$" \
80324 > /dev/null
80325 then
80326 #
80327 # Il file non esiste oppure si tratta di
80328 # `...crt0.s'.
80329 #
80330 true
80331 else
80332 OBJECTS="$OBJECTS $o"
80333 fi
80334 done
80335 #
80336 # File oggetto differente da `...crt0.s'.
80337 #
80338 BASENAME=`basename $a`
80339 EXEC="$a/$BASENAME"
80340 #
80341 rm $EXEC $EXEC.ELF 2> "/dev/null"
80342 #
80343 echo ld --script=applic.sep.ld \
80344 --no-check-sections \
80345 --oformat elf32-i386 \
80346 -o $EXEC.ELF \
80347 $a/crt0.sep.o \
80348 $OBJECTS \
80349 $OBJLIB > link-$BASENAME.link
80350 #
80351 echo ./elf-to-os32 $EXEC.ELF $EXEC \
80352 >> link-$BASENAME.link
80353 #
80354 ld --script=applic.sep.ld \
80355 --no-check-sections \
80356 --oformat elf32-i386 \
80357 -o $EXEC.ELF \
80358 $a/crt0.sep.o \
80359 $OBJECTS \
80360 $OBJLIB
80361 #
80362 ./elf-to-os32 $EXEC.ELF $EXEC
80363 #
80364 if [ -x "$EXEC" ]
80365 then
80366 if mount | grep /mnt/disk.hda.2 > /dev/null
80367 then
80368 mkdir /mnt/disk.hda.2/bin/ 2> /dev/null
80369 rm /mnt/disk.hda.2/bin/$EXEC 2> "/dev/null"
80370 cp -f "$EXEC" /mnt/disk.hda.2/bin
80371 else
80372 echo "[$0] Cannot copy the application "
80373 echo "[$0] $BASENAME inside the disk "
80374 echo "[$0] image!"
80375 break
80376 fi
80377 fi
80378 fi
80379 done
80380 sync
80381 fi
80382 }
80383 #
80384 # Start.
80385 #
80386 if [ -d kernel ] && \
80387 [ -d lib ]
80388 then
80389 OS32PATH=`pwd`
80390 main
80391 else
80392 echo "[$0] Running from a wrong directory!"
80393 fi
|
|
94.1.9
qemu
Si veda la sezione 85.4.
90001 #!/bin/sh
90002 #
90003 #
90004 #
90005 if [ -n "$DISPLAY" ]
90006 then
90007 CURSES=""
90008 else
90009 CURSES="-curses"
90010 fi
90011
90012 if [ "$EUID" = "0" ]
90013 then
90014 # 172.21.11.18 172.21.11.16
90015 # >-----------point to point -----> >-------os32
90016 # tap0 (linux) net1
90017 #
90018 # Dal lato Linux:
90019 # ifconfig tap0 172.21.11.18 pointopoint \
90020 # 172.21.11.16 netmask 255.255.255.255
90021 # route add -host 172.21.11.16 gw 172.21.11.18
90022 #
90023 # Dalla macchina 172.21.254.254:
90024 # route add -host 172.21.11.16 gw 172.21.11.18
90025 #
90026 qemu $CURSES \
90027 -hda disk.hda \
90028 -net nic,macaddr=b0:c4:20:00:00:00,model=ne2k_pci \
90029 -net tap,ifname=tap0,script=./tap0 \
90030 -boot c
90031 else
90032 echo "[$0] Qemu avviato senza privilegi: non"
90033 echo "[$0] funziona la rete!"
90034 echo "[$0] Premi Invio per continuare"
90035 read
90036
90037 qemu $CURSES \
90038 -hda disk.hda \
90039 -net nic,macaddr=b0:c4:20:00:00:00,model=ne2k_pci \
90040 -net user,net=172.21.0.0/16,host=172.21.254.254,\
90041 restrict=n \
90042 -boot c
90043 fi
90044
|
|
94.1.10
syslinux
Si veda la sezione 85.1.
100001 #!/bin/sh
100002 #
100003 #
100004 #
100005 . ./file_image_functions
100006 #
100007 if [ -z "$1" ] || [ -z "$2" ] || [ "$2" -lt "1" ] \
100008 || [ "$2" -gt "4" ]
100009 then
100010 echo "Usage:"
100011 echo ""
100012 echo "$0 DISK_IMAGE_FILE PART_NUMBER"
100013 echo ""
100014 echo "The partition number must be between"
100015 echo " 1 and 4."
100016 echo "No extended partitions are handled!"
100017 else
100018 file_image_partition_syslinux "$1" "$2"
100019 fi
100020 #
|
|
94.1.11
tap0
Si veda la sezione 85.4.
110001 #!/bin/sh
110002
110003
110004 ifconfig tap0 172.21.11.18 pointopoint 172.21.11.16 \
110005 netmask 255.255.255.255
110006 route add -host 172.21.11.16 gw 172.21.11.18
110007
110008
|
|
94.2
os32: «kernel/blk.h»
Si veda la sezione 93.3.
120001 #ifndef _KERNEL_BLK_H
120002 #define _KERNEL_BLK_H 1
120003 //----------------------------------------------------------
120004 #include <sys/types.h>
120005 #include <kernel/driver/ata.h>
120006 //----------------------------------------------------------
120007 #define BLK_SIZE ATA_SECTOR_SIZE // [1]
120008 //
120009 // [1] This value should be the same as the mass memory
120010 // sector size, or a multiple. But with a multiple,
120011 // all simple read and write will be doubled, and
120012 // some race will lock the system, because read and
120013 // write are too frequent for the poor ATA driver
120014 // that I have. :-(
120015 //
120016 //----------------------------------------------------------
120017 #define BLK_CACHE_SIZE 128 // This is
120018 // free!
120019 #define BLK_CACHE_MAX_AGE BLK_CACHE_SIZE-1
120020 typedef struct
120021 {
120022 unsigned int age; // 0=last used
120023 // DEV_CACHE_MAX_AGE=older
120024 dev_t device;
120025 unsigned int n;
120026 char block[BLK_SIZE];
120027 } blk_cache_t;
120028
120029 extern blk_cache_t blk_table[BLK_CACHE_SIZE];
120030 //----------------------------------------------------------
120031 void *blk_ata (dev_t device, int rw, unsigned int n,
120032 void *buffer);
120033 //----------------------------------------------------------
120034 void blk_cache_init (void);
120035 void blk_cache_check (void);
120036 void *blk_cache_read (dev_t device, unsigned int n);
120037 void *blk_cache_save (dev_t device, unsigned int n,
120038 void *block);
120039 //----------------------------------------------------------
120040
120041 #endif
|
|
94.2.1
kernel/blk/blk_ata.c
Si veda la sezione 93.3.1.
130001 #include <sys/os32.h>
130002 #include <kernel/blk.h>
130003 #include <kernel/dev.h>
130004 #include <kernel/driver/ata.h>
130005 #include <kernel/lib_k.h>
130006 #include <kernel/dm.h>
130007 #include <sys/types.h>
130008 #include <ctype.h>
130009 #include <string.h>
130010 //----------------------------------------------------------
130011 #define DEBUG 0
130012 //----------------------------------------------------------
130013 void *
130014 blk_ata (dev_t device, int rw, unsigned int n, void *buffer)
130015 {
130016 ata_sector_t *destination = buffer;
130017 ata_sector_t *source = buffer;
130018 int dev_minor = minor (device);
130019 int d = ((dev_minor & 0x00F0) >> 4);
130020 ptrdiff_t ptrdiff;
130021 int drive;
130022 unsigned int sector = n * (BLK_SIZE / ATA_SECTOR_SIZE);
130023 size_t count = (BLK_SIZE / ATA_SECTOR_SIZE);
130024 int status;
130025 int c;
130026 void *cache;
130027 //
130028 // Convert the table pointer to a drive number.
130029 //
130030 ptrdiff = (((intptr_t) dm_table[d].table)
130031 - ((intptr_t) ata_table));
130032 drive = ptrdiff / (sizeof (ata_t));
130033 //
130034 if (DEBUG)
130035 {
130036 k_printf ("%s: R/W=%i dev=%04x n=%ui ", __FILE__,
130037 rw, (int) device, n);
130038 blk_cache_check ();
130039 }
130040 //
130041 // If reading, check if we already have inside
130042 // cache.
130043 //
130044 if (rw == DEV_READ)
130045 {
130046 cache = blk_cache_read (device, n);
130047 if (cache != NULL)
130048 {
130049 return (cache);
130050 }
130051 }
130052 //
130053 // Read or write.
130054 //
130055 for (c = 0, status = 0;
130056 c < count && status == 0; c++, sector++)
130057 {
130058 //
130059 if (DEBUG)
130060 {
130061 k_printf ("sec=%i ", sector);
130062 }
130063 //
130064 if (rw == DEV_READ)
130065 {
130066 status = ata_read_sector (drive, sector,
130067 &destination[c]);
130068 }
130069 else
130070 {
130071 status = ata_write_sector (drive, sector,
130072 &source[c]);
130073 }
130074 }
130075 //
130076 // If a block was read or written inside ATA
130077 // hardware, then
130078 // save it inside the cache.
130079 //
130080 if (status == 0)
130081 {
130082 cache = blk_cache_save (device, n, buffer);
130083 }
130084 else
130085 {
130086 cache = NULL;
130087 }
130088 //
130089 //
130090 //
130091 if (DEBUG)
130092 {
130093 k_printf ("\n");
130094 }
130095 //
130096 return (cache);
130097 }
|
|
94.2.2
kernel/blk/blk_cache_check.c
Si veda la sezione 93.3.2.
140001 #include <kernel/blk.h>
140002 #include <string.h>
140003 #include <kernel/lib_k.h>
140004 //----------------------------------------------------------
140005 void
140006 blk_cache_check (void)
140007 {
140008 int i;
140009 int j;
140010 //
140011 // check if all ages are present.
140012 //
140013 for (i = 0; i < BLK_CACHE_SIZE; i++)
140014 {
140015 if (blk_table[i].age > BLK_CACHE_MAX_AGE)
140016 {
140017 k_printf
140018 ("blk_table[%i].age > BLK_CACHE_MAX_AGE\n", i);
140019 return;
140020 }
140021 for (j = 0; j < BLK_CACHE_SIZE; j++)
140022 {
140023 if (j != i
140024 && blk_table[i].age == blk_table[j].age)
140025 {
140026 k_printf
140027 ("blk_table[%i].age == "
140028 "blk_table[%i].age\n", i, j);
140029 return;
140030 }
140031 }
140032 }
140033 }
|
|
94.2.3
kernel/blk/blk_cache_init.c
Si veda la sezione 93.3.3.
150001 #include <kernel/blk.h>
150002 //----------------------------------------------------------
150003 void
150004 blk_cache_init (void)
150005 {
150006 int i;
150007 for (i = 0; i < BLK_CACHE_SIZE; i++)
150008 {
150009 blk_table[i].age = i; // Age is from 0 to
150010 // BLK_CACHE_MAX_AGE.
150011 blk_table[i].device = 0;
150012 blk_table[i].n = 0;
150013 }
150014 }
|
|
94.2.4
kernel/blk/blk_cache_read.c
Si veda la sezione 93.3.4.
160001 #include <kernel/blk.h>
160002 #include <string.h>
160003 //----------------------------------------------------------
160004 void *
160005 blk_cache_read (dev_t device, unsigned int n)
160006 {
160007 int i;
160008 int j;
160009 int age;
160010 //
160011 device &= 0xFFF0;
160012 //
160013 for (i = 0; i < BLK_CACHE_SIZE; i++)
160014 {
160015 if (blk_table[i].device == device
160016 && blk_table[i].n == n)
160017 {
160018 age = blk_table[i].age;
160019 for (j = 0; j < BLK_CACHE_SIZE; j++)
160020 {
160021 if (blk_table[j].age < age)
160022 {
160023 blk_table[j].age++;
160024 }
160025 }
160026 blk_table[i].age = 0;
160027 //
160028 return (&blk_table[i].block);
160029 }
160030 }
160031 return (NULL);
160032 }
|
|
94.2.5
kernel/blk/blk_cache_save.c
Si veda la sezione 93.3.4.
170001 #include <kernel/blk.h>
170002 #include <string.h>
170003 //----------------------------------------------------------
170004 void *
170005 blk_cache_save (dev_t device, unsigned int n, void *block)
170006 {
170007 int i;
170008 int j;
170009 int age;
170010 //
170011 device &= 0xFFF0;
170012 //
170013 // Look inside the cache, if we already have
170014 // that old block.
170015 //
170016 for (i = 0; i < BLK_CACHE_SIZE; i++)
170017 {
170018 if (blk_table[i].device == device
170019 && blk_table[i].n == n)
170020 {
170021 age = blk_table[i].age;
170022 for (j = 0; j < BLK_CACHE_SIZE; j++)
170023 {
170024 if (blk_table[j].age < age)
170025 {
170026 blk_table[j].age++;
170027 }
170028 }
170029 blk_table[i].age = 0;
170030 //
170031 // Check if the block is the same memory.
170032 //
170033 if (blk_table[i].block == block)
170034 {
170035 //
170036 // No need to transfer data.
170037 //
170038 ;
170039 }
170040 else
170041 {
170042 memcpy (blk_table[i].block, block,
170043 (size_t) BLK_SIZE);
170044 }
170045 return (&blk_table[i].block);
170046 }
170047 }
170048 //
170049 // The block is new for the cache: must find
170050 // the older and replace it.
170051 //
170052 for (i = 0; i < BLK_CACHE_SIZE; i++)
170053 {
170054 if (blk_table[i].age == BLK_CACHE_MAX_AGE)
170055 {
170056 for (j = 0; j < BLK_CACHE_SIZE; j++)
170057 {
170058 if (blk_table[j].age < BLK_CACHE_MAX_AGE)
170059 {
170060 blk_table[j].age++;
170061 }
170062 }
170063 blk_table[i].age = 0;
170064 blk_table[i].device = device;
170065 blk_table[i].n = n;
170066 memcpy (blk_table[i].block, block,
170067 (size_t) BLK_SIZE);
170068 //
170069 return (&blk_table[i].block);
170070 }
170071 }
170072 //
170073 // It should never happen to fail.
170074 //
170075 return (NULL);
170076 }
|
|
94.2.6
kernel/blk/blk_public.c
Si veda la sezione 93.3.
180001 #include <kernel/blk.h>
180002 //----------------------------------------------------------
180003 blk_cache_t blk_table[BLK_CACHE_SIZE];
|
|
94.3
os32: «kernel/dev.h»
Si veda la sezione 93.4.
190001 #ifndef _KERNEL_DEV_H
190002 #define _KERNEL_DEV_H 1
190003 //----------------------------------------------------------
190004 #include <sys/os32.h>
190005 #include <sys/types.h>
190006 #include <kernel/driver/ata.h>
190007 //----------------------------------------------------------
190008 #define DEV_READ 0
190009 #define DEV_WRITE 1
190010 ssize_t dev_io (pid_t pid, dev_t device, int rw,
190011 off_t offset, void *buffer,
190012 size_t size, int *eof);
190013 //----------------------------------------------------------
190014 // The following functions are used only by `dev_io()'.
190015 //----------------------------------------------------------
190016 ssize_t dev_dm (pid_t pid, dev_t device, int rw,
190017 off_t offset, void *buffer,
190018 size_t size, int *eof);
190019 ssize_t dev_ata (pid_t pid, dev_t device, int rw,
190020 off_t offset, void *buffer,
190021 size_t size, int *eof);
190022 ssize_t dev_mem (pid_t pid, dev_t device, int rw,
190023 off_t offset, void *buffer,
190024 size_t size, int *eof);
190025 ssize_t dev_tty (pid_t pid, dev_t device, int rw,
190026 off_t offset, void *buffer,
190027 size_t size, int *eof);
190028 ssize_t dev_kmem (pid_t pid, dev_t device, int rw,
190029 off_t offset, void *buffer,
190030 size_t size, int *eof);
190031 //----------------------------------------------------------
190032 #endif
|
|
94.3.1
kernel/dev/dev_ata.c
Si veda la sezione 93.4.3.
200001 #include <sys/os32.h>
200002 #include <kernel/dev.h>
200003 #include <kernel/blk.h>
200004 #include <kernel/driver/ata.h>
200005 #include <kernel/lib_k.h>
200006 #include <kernel/dm.h>
200007 #include <sys/types.h>
200008 #include <ctype.h>
200009 #include <errno.h>
200010 //----------------------------------------------------------
200011 ssize_t
200012 dev_ata (pid_t pid, dev_t device, int rw, off_t offset,
200013 void *buffer, size_t size, int *eof)
200014 {
200015 ssize_t m;
200016 ssize_t n = 0;
200017 unsigned char *data_buffer = buffer;
200018 unsigned int n_blk;
200019 int i;
200020 int j = 0;
200021 char *block;
200022 //
200023 // Read the first block.
200024 //
200025 n_blk = offset / BLK_SIZE;
200026 i = offset % BLK_SIZE;
200027 //
200028 block = blk_ata (device, DEV_READ, n_blk, NULL);
200029 if (block == NULL)
200030 {
200031 errset (errno);
200032 return ((ssize_t) - 1);
200033 }
200034 //
200035 // Read or write.
200036 //
200037 if (rw == DEV_READ)
200038 {
200039 while (size)
200040 {
200041 for (;
200042 i < BLK_SIZE && size > 0;
200043 i++, j++, n++, size--, offset++)
200044 {
200045 data_buffer[j] = block[i];
200046 }
200047 if (size)
200048 {
200049 n_blk = offset / BLK_SIZE;
200050 i = offset % BLK_SIZE;
200051 block = blk_ata (device, DEV_READ, n_blk,
200052 NULL);
200053 if (block == NULL)
200054 {
200055 errset (errno);
200056 return (n); // Up to the last
200057 // block read.
200058 }
200059 }
200060 }
200061 }
200062 else
200063 {
200064 //
200065 // Write.
200066 //
200067 while (size)
200068 {
200069 //
200070 // The last block was written, so update
200071 // the counter `m'.
200072 //
200073 m = n;
200074 //
200075 for (;
200076 i < BLK_SIZE && size > 0;
200077 i++, j++, n++, size--, offset++)
200078 {
200079 block[i] = data_buffer[j];
200080 }
200081 block = blk_ata (device, DEV_WRITE, n_blk, block);
200082 if (block == NULL)
200083 {
200084 errset (errno);
200085 return (m); // Up to the last
200086 // block written.
200087 }
200088 if (size)
200089 {
200090 n_blk = offset / BLK_SIZE;
200091 i = offset % BLK_SIZE;
200092 block = blk_ata (device, DEV_READ, n_blk,
200093 NULL);
200094 if (block == NULL)
200095 {
200096 errset (errno);
200097 return (m); // Up to the last
200098 // block written.
200099 }
200100 }
200101 }
200102 }
200103 //
200104 // Everything was right, so `n' is valid for both
200105 // read or write.
200106 //
200107 return (n);
200108 }
|
|
94.3.2
kernel/dev/dev_dm.c
Si veda la sezione 93.4.2.
210001 #include <sys/os32.h>
210002 #include <kernel/dev.h>
210003 #include <kernel/driver/ata.h>
210004 #include <kernel/lib_k.h>
210005 #include <kernel/dm.h>
210006 #include <sys/types.h>
210007 #include <ctype.h>
210008 #include <errno.h>
210009 //----------------------------------------------------------
210010 ssize_t
210011 dev_dm (pid_t pid, dev_t device, int rw, off_t offset,
210012 void *buffer, size_t size, int *eof)
210013 {
210014 int dev_minor = minor (device);
210015 int p = dev_minor & 0x000F;
210016 int d = ((dev_minor & 0x00F0) >> 4);
210017 //
210018 // If it is a partition, must verify if such
210019 // partition exists.
210020 //
210021 if (p)
210022 {
210023 //
210024 // It is a partition.
210025 //
210026 if (dm_table[d].part[p].type == PART_TYPE_NONE)
210027 {
210028 errset (ENODEV);
210029 return ((ssize_t) - 1);
210030 }
210031 }
210032 //
210033 // Shift the offset to the start of partition.
210034 //
210035 offset += (dm_table[d].part[p].start);
210036 //
210037 // Call the right hardware driver.
210038 //
210039 switch (dm_table[d].type)
210040 {
210041 case DM_TYPE_ATA:
210042 return (dev_ata
210043 (pid, device, rw, offset, buffer, size, eof));
210044 break;
210045 default:
210046 errset (ENODEV);
210047 return ((ssize_t) - 1);
210048 }
210049 }
|
|
94.3.3
kernel/dev/dev_io.c
Si veda la sezione 93.4.1.
220001 #include <sys/os32.h>
220002 #include <kernel/dev.h>
220003 #include <sys/types.h>
220004 #include <errno.h>
220005 #include <kernel/ibm_i386.h>
220006 #include <kernel/proc.h>
220007 #include <string.h>
220008 #include <signal.h>
220009 #include <kernel/lib_k.h>
220010 #include <ctype.h>
220011 #include <kernel/driver/tty.h>
220012 //----------------------------------------------------------
220013 ssize_t
220014 dev_io (pid_t pid, dev_t device, int rw, off_t offset,
220015 void *buffer, size_t size, int *eof)
220016 {
220017 int dev_major = major (device);
220018 if (rw != DEV_READ && rw != DEV_WRITE)
220019 {
220020 errset (EIO);
220021 return (-1);
220022 }
220023 switch (dev_major)
220024 {
220025 case DEV_MEM_MAJOR:
220026 return (dev_mem
220027 (pid, device, rw, offset, buffer, size, eof));
220028 case DEV_TTY_MAJOR:
220029 return (dev_tty
220030 (pid, device, rw, offset, buffer, size, eof));
220031 case DEV_CONSOLE_MAJOR:
220032 return (dev_tty
220033 (pid, device, rw, offset, buffer, size, eof));
220034 case DEV_DM_MAJOR:
220035 return (dev_dm
220036 (pid, device, rw, offset, buffer, size, eof));
220037 case DEV_KMEM_MAJOR:
220038 return (dev_kmem
220039 (pid, device, rw, offset, buffer, size, eof));
220040 default:
220041 errset (ENODEV);
220042 return (-1);
220043 }
220044 }
|
|
94.3.4
kernel/dev/dev_kmem.c
Si veda la sezione 93.4.4.
230001 #include <sys/os32.h>
230002 #include <kernel/dev.h>
230003 #include <sys/types.h>
230004 #include <errno.h>
230005 #include <kernel/memory.h>
230006 #include <kernel/proc.h>
230007 #include <kernel/net/arp.h>
230008 #include <kernel/net/route.h>
230009 #include <kernel/net.h>
230010 #include <string.h>
230011 #include <signal.h>
230012 #include <ctype.h>
230013 //----------------------------------------------------------
230014 ssize_t
230015 dev_kmem (pid_t pid, dev_t device, int rw,
230016 off_t offset, void *buffer, size_t size, int *eof)
230017 {
230018 inode_t *inode;
230019 sb_t *sb;
230020 file_t *file;
230021 void *start;
230022 char *m;
230023 //
230024 // Only read is allowed.
230025 //
230026 if (rw != DEV_READ)
230027 {
230028 errset (EIO); // I/O error.
230029 return ((ssize_t) - 1);
230030 }
230031 //
230032 // Only positive offset is allowed.
230033 //
230034 if (offset < 0)
230035 {
230036 errset (EIO); // I/O error.
230037 return ((ssize_t) - 1);
230038 }
230039 //
230040 // Read is selected (and is the only access
230041 // allowed).
230042 //
230043 switch (device)
230044 {
230045 case DEV_KMEM_PS:
230046 //
230047 // Verify if the selected slot can be read.
230048 //
230049 if (offset >= PROCESS_MAX)
230050 {
230051 errset (EIO); // I/O error.
230052 return ((ssize_t) - 1);
230053 }
230054 //
230055 // Correct the size to be read.
230056 //
230057 if (sizeof (proc_t) < size)
230058 {
230059 size = sizeof (proc_t);
230060 }
230061 //
230062 // Get the pointer to the selected slot.
230063 //
230064 start = proc_reference ((pid_t) offset);
230065 break;
230066 case DEV_KMEM_MMP:
230067 //
230068 // Correct the size to be read.
230069 //
230070 if (offset >= (MEM_MAX_BLOCKS / 8))
230071 {
230072 *eof = 1;
230073 errset (EIO); // I/O error.
230074 return ((ssize_t) - 1);
230075 }
230076 //
230077 // Reduce size if necessary.
230078 //
230079 if ((offset + size) > (MEM_MAX_BLOCKS / 8))
230080 {
230081 size = ((MEM_MAX_BLOCKS / 8) - offset);
230082 }
230083 //
230084 // Get the pointer to the map: offset is not
230085 // taken
230086 // into consideration.
230087 //
230088 m = (char *) mb_reference ();
230089 //
230090 start = &m[offset];
230091 //
230092 break;
230093 case DEV_KMEM_SB:
230094 //
230095 // Verify if the selected slot can be read.
230096 //
230097 if (offset >= SB_MAX_SLOTS)
230098 {
230099 errset (EIO); // I/O error.
230100 return ((ssize_t) - 1);
230101 }
230102 //
230103 // Get a reference to the super block table.
230104 //
230105 sb = sb_reference (0);
230106 //
230107 // Correct the size to be read.
230108 //
230109 if (sizeof (sb_t) < size)
230110 {
230111 size = sizeof (sb_t);
230112 }
230113 //
230114 // Get the pointer to the selected super block
230115 // slot.
230116 //
230117 start = &sb[offset];
230118 break;
230119 case DEV_KMEM_INODE:
230120 //
230121 // Verify if the selected slot can be read.
230122 //
230123 if (offset >= INODE_MAX_SLOTS)
230124 {
230125 errset (EIO); // I/O error.
230126 return ((ssize_t) - 1);
230127 }
230128 //
230129 // Get a reference to the inode table.
230130 //
230131 inode = inode_reference (0, 0);
230132 //
230133 // Correct the size to be read.
230134 //
230135 if (sizeof (inode_t) < size)
230136 {
230137 size = sizeof (inode_t);
230138 }
230139 //
230140 // Get the pointer to the selected inode slot.
230141 //
230142 start = &inode[offset];
230143 break;
230144 case DEV_KMEM_FILE:
230145 //
230146 // Verify if the selected slot can be read.
230147 //
230148 if (offset >= FILE_MAX_SLOTS)
230149 {
230150 errset (EIO); // I/O error.
230151 return ((ssize_t) - 1);
230152 }
230153 //
230154 // Get a reference to the file table.
230155 //
230156 file = file_reference (0);
230157 //
230158 // Correct the size to be read.
230159 //
230160 if (sizeof (file_t) < size)
230161 {
230162 size = sizeof (file_t);
230163 }
230164 //
230165 // Get the pointer to the selected inode slot.
230166 //
230167 start = &file[offset];
230168 break;
230169 case DEV_KMEM_ARP:
230170 //
230171 // Verify if the selected slot can be read.
230172 //
230173 if (offset >= ARP_MAX_ITEMS)
230174 {
230175 errset (EIO); // I/O error.
230176 return ((ssize_t) - 1);
230177 }
230178 //
230179 // Correct the size to be read.
230180 //
230181 if (sizeof (arp_t) < size)
230182 {
230183 size = sizeof (arp_t);
230184 }
230185 //
230186 // Get the pointer to the selected ARP item.
230187 //
230188 start = &arp_table[offset];
230189 break;
230190 case DEV_KMEM_NET:
230191 //
230192 // Verify if the selected slot can be read.
230193 //
230194 if (offset >= NET_MAX_DEVICES)
230195 {
230196 errset (EIO); // I/O error.
230197 return ((ssize_t) - 1);
230198 }
230199 //
230200 // Correct the size to be read.
230201 //
230202 if (sizeof (net_t) < size)
230203 {
230204 size = sizeof (net_t);
230205 }
230206 //
230207 // Get the pointer to the selected NET table
230208 // item.
230209 //
230210 start = &net_table[offset];
230211 break;
230212 case DEV_KMEM_ROUTE:
230213 //
230214 // Verify if the selected slot can be read.
230215 //
230216 if (offset >= ROUTE_MAX_ROUTES)
230217 {
230218 errset (EIO); // I/O error.
230219 return ((ssize_t) - 1);
230220 }
230221 //
230222 // Correct the size to be read.
230223 //
230224 if (sizeof (route_t) < size)
230225 {
230226 size = sizeof (route_t);
230227 }
230228 //
230229 // Get the pointer to the selected NET table
230230 // item.
230231 //
230232 start = &route_table[offset];
230233 break;
230234 default:
230235 errset (ENODEV); // No such device.
230236 return ((ssize_t) - 1);
230237 }
230238 //
230239 // At this point, data is ready to be copied to the
230240 // buffer.
230241 //
230242 memcpy (buffer, start, size);
230243 //
230244 // Return size read.
230245 //
230246 return (size);
230247 }
|
|
94.3.5
kernel/dev/dev_mem.c
Si veda la sezione 93.4.5.
240001 #include <sys/os32.h>
240002 #include <kernel/dev.h>
240003 #include <sys/types.h>
240004 #include <errno.h>
240005 #include <kernel/memory.h>
240006 #include <kernel/ibm_i386.h>
240007 #include <kernel/proc.h>
240008 #include <string.h>
240009 #include <signal.h>
240010 #include <kernel/lib_k.h>
240011 #include <ctype.h>
240012 //----------------------------------------------------------
240013 ssize_t
240014 dev_mem (pid_t pid, dev_t device, int rw, off_t offset,
240015 void *buffer, size_t size, int *eof)
240016 {
240017 uint8_t *buffer08 = (uint8_t *) buffer;
240018 uint16_t *buffer16 = (uint16_t *) buffer;
240019 ssize_t n;
240020
240021 if (device == DEV_MEM) // DEV_MEM
240022 {
240023 if (rw == DEV_READ)
240024 {
240025 memcpy (buffer, (void *) (int) offset, size);
240026 n = size;
240027 }
240028 else
240029 {
240030 if (pid == 0)
240031 {
240032 memcpy ((void *) (int) offset, buffer, size);
240033 n = size;
240034 }
240035 else
240036 {
240037 k_printf
240038 ("kernel alert: only the kernel "
240039 "can write the memory where it "
240040 "likes!\n");
240041 errset (EIO); // I/O error.
240042 return ((ssize_t) - 1);
240043 }
240044 }
240045 }
240046 else if (device == DEV_NULL) // DEV_NULL
240047 {
240048 n = 0;
240049 }
240050 else if (device == DEV_ZERO) // DEV_ZERO
240051 {
240052 if (rw == DEV_READ)
240053 {
240054 for (n = 0; n < size; n++)
240055 {
240056 buffer08[n] = 0;
240057 }
240058 }
240059 else
240060 {
240061 n = 0;
240062 }
240063 }
240064 else if (device == DEV_PORT) // DEV_PORT
240065 {
240066 if (rw == DEV_READ)
240067 {
240068 if (size == 1)
240069 {
240070 buffer08[0] = in_8 (offset);
240071 n = 1;
240072 }
240073 else if (size == 2)
240074 {
240075 buffer16[0] = in_16 (offset);
240076 n = 2;
240077 }
240078 else
240079 {
240080 n = 0;
240081 }
240082 }
240083 else
240084 {
240085 if (size == 1)
240086 {
240087 out_8 (offset, buffer08[0]);
240088 }
240089 else if (size == 2)
240090 {
240091 out_16 (offset, buffer16[0]);
240092 n = 2;
240093 }
240094 else
240095 {
240096 n = 0;
240097 }
240098 }
240099 }
240100 else
240101 {
240102 errset (ENODEV);
240103 return ((ssize_t) - 1);
240104 }
240105 return (n);
240106 }
|
|
94.3.6
kernel/dev/dev_tty.c
Si veda la sezione 93.4.6.
250001 #include <sys/os32.h>
250002 #include <kernel/dev.h>
250003 #include <sys/types.h>
250004 #include <errno.h>
250005 #include <kernel/memory.h>
250006 #include <kernel/ibm_i386.h>
250007 #include <kernel/proc.h>
250008 #include <string.h>
250009 #include <signal.h>
250010 #include <kernel/lib_k.h>
250011 #include <ctype.h>
250012 #include <kernel/driver/tty.h>
250013 //----------------------------------------------------------
250014 ssize_t
250015 dev_tty (pid_t pid, dev_t device, int rw, off_t offset,
250016 void *buffer, size_t size, int *eof)
250017 {
250018 uint8_t *buffer08 = (uint8_t *) buffer;
250019 ssize_t n;
250020 proc_t *ps;
250021 int key;
250022 //
250023 // Get process. Variable `ps' will be `NULL' if the
250024 // process ID is
250025 // not valid.
250026 //
250027 ps = proc_reference (pid);
250028 //
250029 // Convert `DEV_TTY' with the controlling terminal
250030 // for the process.
250031 //
250032 if (device == DEV_TTY)
250033 {
250034 device = ps->device_tty;
250035 //
250036 // As a last resort, use the generic
250037 // `DEV_CONSOLE'.
250038 //
250039 if (device == DEV_UNDEFINED || device == DEV_TTY)
250040 {
250041 device = DEV_CONSOLE;
250042 }
250043 }
250044 //
250045 // Convert `DEV_CONSOLE' to the currently active
250046 // console.
250047 //
250048 if (device == DEV_CONSOLE)
250049 {
250050 device = tty_console ((dev_t) 0);
250051 //
250052 // As a last resort, use the first console:
250053 // `DEV_CONSOLE0'.
250054 //
250055 if (device == DEV_UNDEFINED || device == DEV_TTY)
250056 {
250057 device = DEV_CONSOLE0;
250058 }
250059 }
250060 //
250061 // Read or write.
250062 //
250063 if (rw == DEV_READ)
250064 {
250065 for (n = 0; n < size; n++)
250066 {
250067 key = tty_read (device);
250068 if (key == 0 && n == 0)
250069 {
250070 //
250071 // A single line contains zero: this is
250072 // made by a VEOF
250073 // character (^d), that is, the input is
250074 // closed,
250075 // so return zero read and EOF.
250076 //
250077 *eof = 1;
250078 return (0);
250079 }
250080 else if (key == -1 && n == 0)
250081 {
250082 //
250083 // At the moment, there is just nothing
250084 // to read.
250085 //
250086 errset (EAGAIN);
250087 return (-1);
250088 }
250089 else if (key == -1 && n > 0)
250090 {
250091 //
250092 // Finished to read.
250093 //
250094 break;
250095 }
250096 else
250097 {
250098 buffer08[n] = key;
250099 }
250100 }
250101 }
250102 else
250103 {
250104 for (n = 0; n < size; n++)
250105 {
250106 tty_write (device, (int) buffer08[n]);
250107 }
250108 }
250109 return (n);
250110 }
|
|
94.4
os32: «kernel/dm.h»
Si veda la sezione 93.5.
260001 #ifndef _KERNEL_DM_H
260002 #define _KERNEL_DM_H 1
260003 //----------------------------------------------------------
260004 #include <stdint.h>
260005 #include <sys/types.h>
260006 #include <kernel/part.h>
260007 //----------------------------------------------------------
260008 #define DM_MAX_DEVICES 4
260009 #define DM_TYPE_NONE 0
260010 #define DM_TYPE_ATA 1
260011 //
260012 typedef struct
260013 {
260014 int type;
260015 void *table;
260016 struct
260017 {
260018 off_t start;
260019 size_t size;
260020 uint8_t type;
260021 } part[PART_MAX + 1];
260022 } dm_t;
260023 //
260024 extern dm_t dm_table[DM_MAX_DEVICES];
260025 //----------------------------------------------------------
260026 void dm_init (void);
260027 //----------------------------------------------------------
260028 #endif
|
|
94.4.1
kernel/dm/dm_init.c
Si veda la sezione 93.5.
270001 #include <kernel/dm.h>
270002 #include <kernel/part.h>
270003 #include <kernel/driver/ata.h>
270004 #include <kernel/lib_k.h>
270005 #include <stdint.h>
270006 #include <errno.h>
270007 //----------------------------------------------------------
270008 void
270009 dm_init (void)
270010 {
270011 int d;
270012 int a;
270013 int p;
270014 ata_sector_t sector_buffer;
270015 part_t *part;
270016 int status;
270017 //
270018 // Reset the data-memory table.
270019 //
270020 for (d = 0; d < DM_MAX_DEVICES; d++)
270021 {
270022 dm_table[d].type = DM_TYPE_NONE;
270023 dm_table[d].table = NULL;
270024 dm_table[d].part[0].start = 0;
270025 dm_table[d].part[0].size = 0;
270026 dm_table[d].part[0].type = PART_TYPE_NO_PART;
270027 for (p = 0; p < PART_MAX; p++)
270028 {
270029 dm_table[d].part[p + 1].start = 0;
270030 dm_table[d].part[p + 1].size = 0;
270031 dm_table[d].part[p + 1].type = PART_TYPE_NONE;
270032 }
270033 }
270034 //
270035 // Reset data-memory index.
270036 //
270037 d = 0;
270038 //
270039 // Init ATA devices.
270040 //
270041 ata_init ();
270042 //
270043 // Assign ATA devices to the first data-memory
270044 // items.
270045 //
270046 for (a = 0; a < ATA_MAX_DEVICES; a++)
270047 {
270048 if (ata_table[a].present == 0)
270049 {
270050 //
270051 // Current data-memory device will be
270052 // used for the next ATA device, if any.
270053 //
270054 continue;
270055 }
270056 //
270057 // Show something.
270058 //
270059 k_printf ("[%s] ATA drive=%i total sectors=%i\n",
270060 __func__, a, (int) ata_table[d].sectors);
270061 //
270062 dm_table[d].type = DM_TYPE_ATA;
270063 dm_table[d].table = &ata_table[a];
270064 dm_table[d].part[0].start = 0;
270065 dm_table[d].part[0].size = ata_table[a].sectors;
270066 dm_table[d].part[0].type = PART_TYPE_NO_PART;
270067 //
270068 // Read partitions.
270069 //
270070 status = ata_read_sector (a, 0, §or_buffer);
270071 //
270072 if (status)
270073 {
270074 errset (errno);
270075 k_perror (NULL);
270076 }
270077 else
270078 {
270079 part =
270080 (((void *) §or_buffer) + PART_TABLE_OFF);
270081 //
270082 for (p = 0; p < PART_MAX; p++)
270083 {
270084 //
270085 dm_table[d].part[p + 1].start =
270086 part->l_start * ATA_SECTOR_SIZE;
270087 dm_table[d].part[p + 1].size =
270088 part->size * ATA_SECTOR_SIZE;
270089 dm_table[d].part[p + 1].type = part->type;
270090 //
270091 // Show info.
270092 //
270093 if (part->type != 0)
270094 {
270095 k_printf ("[%s] partition type=%02x "
270096 "start sector=%i "
270097 "total sectors=%i\n",
270098 __func__, (int) part->type,
270099 (int) part->l_start,
270100 (int) part->size);
270101 }
270102 //
270103 part++;
270104 }
270105 }
270106 //
270107 // Next data-memory device.
270108 //
270109 d++;
270110 }
270111 }
|
|
94.4.2
kernel/dm/dm_public.c
Si veda la sezione 93.5.
280001 #include <kernel/dm.h>
280002 //----------------------------------------------------------
280003 dm_t dm_table[DM_MAX_DEVICES];
|
|
94.4.3
kernel/driver/ata.h
Si veda la sezione 93.2.
290001 #ifndef _KERNEL_DRIVER_ATA_H
290002 #define _KERNEL_DRIVER_ATA_H 1
290003 //----------------------------------------------------------
290004 #include <stdint.h>
290005 #include <sys/types.h>
290006 #include <time.h>
290007 //----------------------------------------------------------
290008 //
290009 // I/O ports, used to access ATA bus registers. These
290010 // I/O ports are different for every ATA bus.
290011 //
290012 #define ATA0_DATA 0x1F0 // r/w
290013 #define ATA0_FEATURE 0x1F1 // -/w
290014 #define ATA0_ERROR 0x1F1 // r/-
290015 #define ATA0_COUNT 0x1F2 // r/w
290016 #define ATA0_LOW 0x1F3 // r/w
290017 #define ATA0_MID 0x1F4 // r/w
290018 #define ATA0_HIGH 0x1F5 // r/w
290019 #define ATA0_DEVICE 0x1F6 // r/w
290020 #define ATA0_COMMAND 0x1F7 // -/w
290021 #define ATA0_STATUS 0x1F7 // r/- regular
290022 // status
290023 #define ATA0_CONTROL 0x3F6 // -/w
290024 #define ATA0_ALTERNATE 0x3F6 // w/-
290025 // alternate
290026 // status
290027 //
290028 #define ATA1_DATA 0x170 // r/w
290029 #define ATA1_FEATURE 0x171 // -/w
290030 #define ATA1_ERROR 0x171 // r/-
290031 #define ATA1_COUNT 0x172 // r/w
290032 #define ATA1_LOW 0x173 // r/w
290033 #define ATA1_MID 0x174 // r/w
290034 #define ATA1_HIGH 0x175 // r/w
290035 #define ATA1_DEVICE 0x176 // r/w
290036 #define ATA1_COMMAND 0x177 // -/w
290037 #define ATA1_STATUS 0x177 // r/- regular
290038 // status
290039 #define ATA1_CONTROL 0x376 // -/w
290040 #define ATA1_ALTERNATE 0x376 // w/-
290041 // alternate
290042 // status
290043 //
290044 #define ATA2_DATA 0x1E8 // r/w
290045 #define ATA2_FEATURE 0x1E9 // -/w
290046 #define ATA2_ERROR 0x1E9 // r/-
290047 #define ATA2_COUNT 0x1EA // r/w
290048 #define ATA2_LOW 0x1EB // r/w
290049 #define ATA2_MID 0x1EC // r/w
290050 #define ATA2_HIGH 0x1ED // r/w
290051 #define ATA2_DEVICE 0x1EE // r/w
290052 #define ATA2_COMMAND 0x1EF // -/w
290053 #define ATA2_STATUS 0x1EF // r/- regular
290054 // status
290055 #define ATA2_CONTROL 0x3E6 // -/w
290056 #define ATA2_ALTERNATE 0x3E6 // w/-
290057 // alternate
290058 // status
290059 //
290060 #define ATA3_DATA 0x168 // r/w
290061 #define ATA3_FEATURE 0x169 // -/w
290062 #define ATA3_ERROR 0x169 // r/-
290063 #define ATA3_COUNT 0x16A // r/w
290064 #define ATA3_LOW 0x16B // r/w
290065 #define ATA3_MID 0x16C // r/w
290066 #define ATA3_HIGH 0x16D // r/w
290067 #define ATA3_DEVICE 0x16E // r/w
290068 #define ATA3_COMMAND 0x16F // -/w
290069 #define ATA3_STATUS 0x16F // r/- regular
290070 // status
290071 #define ATA3_CONTROL 0x366 // -/w
290072 #define ATA3_ALTERNATE 0x366 // w/-
290073 // alternate
290074 // status
290075 //
290076 // Status register flags (regular or alternate).
290077 //
290078 #define ATA_STATUS_BSY 0x80 // Busy
290079 #define ATA_STATUS_DRDY 0x40 // Ready
290080 #define ATA_STATUS_DF 0x20 // Drive Fault
290081 #define ATA_STATUS_DRQ 0x08 // Data
290082 // request
290083 #define ATA_STATUS_ERR 0x01 // Error
290084 //
290085 // Values to put to the device register
290086 //
290087 #define ATA_DEVICE_CHS 0x00
290088 #define ATA_DEVICE_LBA 0x40
290089 #define ATA_DEVICE_MASTER 0x00
290090 #define ATA_DEVICE_SLAVE 0x10
290091 //
290092 // Values to put to the command register
290093 //
290094 #define ATA_COMMAND_IDENTIFY_DEVICE 0xEC
290095 #define ATA_COMMAND_READ_SECTORS 0x20
290096 #define ATA_COMMAND_WRITE_SECTORS 0x30
290097 #define ATA_COMMAND_FLUSH_CACHE 0xE7
290098 //
290099 // Values to put to the control register
290100 // (device control register).
290101 //
290102 #define ATA_CONTROL_HOB 0x80
290103 #define ATA_CONTROL_SRST 0x04 // Software
290104 // reset.
290105 #define ATA_CONTROL_NIEN 0x01 // No
290106 // Interrupt
290107 // enabled.
290108 //
290109 //
290110 //
290111 #define ATA_MAX_DEVICES 8 // Fixed.
290112 #define ATA_SECTOR_SIZE 512 // Fixed.
290113 #define ATA_TIMEOUT \
290114 ((clock_t) (CLOCKS_PER_SEC * 1)) // 1 s
290115 #define ATA_TIMEOUT_FLUSH \
290116 ((clock_t) (CLOCKS_PER_SEC * 10)) // 10 s
290117 //
290118 //
290119 //
290120 typedef struct
290121 {
290122 unsigned short r_data;
290123 unsigned short r_feature;
290124 unsigned short r_error;
290125 unsigned short r_count;
290126 unsigned short r_low;
290127 unsigned short r_mid;
290128 unsigned short r_high;
290129 unsigned short r_device;
290130 unsigned short r_command;
290131 unsigned short r_status;
290132 unsigned short r_control;
290133 unsigned short r_alternate;
290134 unsigned char bus;
290135 unsigned char target;
290136 unsigned char present;
290137 uint16_t id[ATA_SECTOR_SIZE / 2];
290138 unsigned int sectors;
290139 } ata_t;
290140 //
290141 typedef struct
290142 {
290143 char byte[ATA_SECTOR_SIZE];
290144 } ata_sector_t;
290145 //
290146 extern ata_t ata_table[ATA_MAX_DEVICES];
290147 //----------------------------------------------------------
290148 void ata_init (void);
290149 void ata_reset (int drive);
290150 int ata_valid (int drive);
290151 //----------------------------------------------------------
290152 int ata_cmd_identify_device (int drive, void *buffer);
290153 int ata_cmd_read_sectors (int drive,
290154 unsigned int sector,
290155 unsigned char count,
290156 void *buffer);
290157 int ata_cmd_write_sectors (int drive,
290158 unsigned int sector,
290159 unsigned char count,
290160 void *buffer);
290161 int ata_device (int drive, unsigned int sector);
290162 //----------------------------------------------------------
290163 int ata_rdy (int drive, clock_t timeout);
290164 int ata_drq (int drive, clock_t timeout);
290165 int ata_lba28 (int drive, unsigned int sector,
290166 unsigned char count);
290167 //----------------------------------------------------------
290168 #define ata_read_sector(drive, sector, buffer) \
290169 (ata_cmd_read_sectors ((int) drive, \
290170 (unsigned int) sector, \
290171 (unsigned char) 1, (void *) buffer))
290172 //
290173 #define ata_write_sector(drive, sector, buffer) \
290174 (ata_cmd_write_sectors ((int) drive, \
290175 (unsigned int) sector, \
290176 (unsigned char) 1, (void *) buffer))
290177 //----------------------------------------------------------
290178 #endif
|
|
94.4.4
kernel/driver/ata/ata_cmd_identify_device.c
Si veda la sezione 93.2.
300001 #include <kernel/driver/ata.h>
300002 #include <kernel/lib_k.h>
300003 #include <kernel/ibm_i386.h>
300004 #include <stdint.h>
300005 #include <errno.h>
300006 //----------------------------------------------------------
300007 int
300008 ata_cmd_identify_device (int drive, void *buffer)
300009 {
300010 unsigned char status;
300011 int s;
300012 int i;
300013 uint16_t *id = buffer;
300014 //
300015 // Register `device'.
300016 //
300017 s = ata_device (drive, 0);
300018 if (s < 0)
300019 {
300020 errset (errno);
300021 return (-1);
300022 }
300023 //
300024 // Send `command'
300025 //
300026 out_8 (ata_table[drive].r_command,
300027 ATA_COMMAND_IDENTIFY_DEVICE);
300028 //
300029 // Read the regular status port.
300030 //
300031 status = in_8 (ata_table[drive].r_status);
300032 //
300033 // If the status is zero, there is no drive.
300034 //
300035 if (status == 0)
300036 {
300037 //
300038 // Clear the `id[]' array and return.
300039 //
300040 for (i = 0; i < (ATA_SECTOR_SIZE / 2); i++)
300041 {
300042 id[i] = 0;
300043 }
300044 return (0);
300045 }
300046 //
300047 // Wait for the drive ready to send data.
300048 //
300049 s = ata_drq (drive, ATA_TIMEOUT);
300050 if (s < 0)
300051 {
300052 errset (errno);
300053 return (-1);
300054 }
300055 //
300056 // Read data.
300057 //
300058 for (i = 0; i < (ATA_SECTOR_SIZE / 2); i++)
300059 {
300060 id[i] = in_16 (ata_table[drive].r_data);
300061 }
300062 //
300063 // Return.
300064 //
300065 return (0);
300066 }
|
|
94.4.5
kernel/driver/ata/ata_cmd_read_sectors.c
Si veda la sezione 93.2.
310001 #include <kernel/driver/ata.h>
310002 #include <kernel/lib_k.h>
310003 #include <kernel/ibm_i386.h>
310004 #include <stdint.h>
310005 #include <errno.h>
310006 //----------------------------------------------------------
310007 int
310008 ata_cmd_read_sectors (int drive, unsigned int sector,
310009 unsigned char count, void *buffer)
310010 {
310011 int s;
310012 int i;
310013 int c;
310014 uint16_t *destination = buffer;
310015 //
310016 // Set LBA 28 parameters.
310017 //
310018 s = ata_lba28 (drive, sector, count);
310019 if (s < 0)
310020 {
310021 errset (errno);
310022 return (-1);
310023 }
310024 //
310025 // Send `command'
310026 //
310027 out_8 (ata_table[drive].r_command,
310028 ATA_COMMAND_READ_SECTORS);
310029 //
310030 // Parameter `count' equal to zero means 256
310031 // sectors.
310032 //
310033 if (count == 0)
310034 {
310035 c = 256;
310036 }
310037 else
310038 {
310039 c = count;
310040 }
310041 //
310042 // Read `c' sectors.
310043 //
310044 for (; c > 0; c--)
310045 {
310046 s = ata_drq (drive, ATA_TIMEOUT);
310047 if (s < 0)
310048 {
310049 errset (errno);
310050 return (-1);
310051 }
310052 //
310053 // Read sector.
310054 //
310055 for (i = 0; i < (ATA_SECTOR_SIZE / 2); i++)
310056 {
310057 destination[i] = in_16 (ata_table[drive].r_data);
310058 }
310059 }
310060 //
310061 // Wait that the device returns ready.
310062 //
310063 s = ata_rdy (drive, ATA_TIMEOUT);
310064 if (s < 0)
310065 {
310066 errset (errno);
310067 return (-1);
310068 }
310069 //
310070 // Return.
310071 //
310072 return (0);
310073 }
|
|
94.4.6
kernel/driver/ata/ata_cmd_write_sectors.c
Si veda la sezione 93.2.
320001 #include <kernel/driver/ata.h>
320002 #include <kernel/lib_k.h>
320003 #include <kernel/ibm_i386.h>
320004 #include <stdint.h>
320005 #include <errno.h>
320006 //----------------------------------------------------------
320007 int
320008 ata_cmd_write_sectors (int drive, unsigned int sector,
320009 unsigned char count, void *buffer)
320010 {
320011 int s;
320012 int i;
320013 int c;
320014 uint16_t *source = buffer;
320015 //
320016 // Set LBA 28 parameters.
320017 //
320018 s = ata_lba28 (drive, sector, count);
320019 if (s < 0)
320020 {
320021 errset (errno);
320022 return (-1);
320023 }
320024 //
320025 // Send `command'
320026 //
320027 out_8 (ata_table[drive].r_command,
320028 ATA_COMMAND_WRITE_SECTORS);
320029 //
320030 // Parameter `count' equal to zero means 256
320031 // sectors.
320032 //
320033 if (count == 0)
320034 {
320035 c = 256;
320036 }
320037 else
320038 {
320039 c = count;
320040 }
320041 //
320042 // Read `c' sectors.
320043 //
320044 for (; c > 0; c--)
320045 {
320046 s = ata_drq (drive, ATA_TIMEOUT);
320047 if (s < 0)
320048 {
320049 errset (errno);
320050 return (-1);
320051 }
320052 //
320053 // Write sector.
320054 //
320055 for (i = 0; i < (ATA_SECTOR_SIZE / 2); i++)
320056 {
320057 out_16 (ata_table[drive].r_data, source[i]);
320058 }
320059 }
320060 //
320061 // Wait that the device returns ready.
320062 //
320063 s = ata_rdy (drive, ATA_TIMEOUT);
320064 if (s < 0)
320065 {
320066 errset (errno);
320067 return (-1);
320068 }
320069 //
320070 // Now flush cache.
320071 //
320072 out_8 (ata_table[drive].r_command,
320073 ATA_COMMAND_FLUSH_CACHE);
320074 //
320075 // Then wait that the device returns ready.
320076 //
320077 s = ata_rdy (drive, ATA_TIMEOUT_FLUSH);
320078 if (s < 0)
320079 {
320080 errset (errno);
320081 return (-1);
320082 }
320083 //
320084 // Return.
320085 //
320086 return (0);
320087 }
|
|
94.4.7
kernel/driver/ata/ata_device.c
Si veda la sezione 93.2.
330001 #include <kernel/driver/ata.h>
330002 #include <kernel/lib_s.h>
330003 #include <kernel/ibm_i386.h>
330004 #include <stdint.h>
330005 #include <errno.h>
330006 //----------------------------------------------------------
330007 int
330008 ata_device (int drive, unsigned int sector)
330009 {
330010 unsigned char device;
330011 int s;
330012 //
330013 // Verify `drive' argument.
330014 //
330015 s = ata_valid (drive);
330016 if (s < 0)
330017 {
330018 errset (EINVAL);
330019 return (-1);
330020 }
330021 //
330022 // Start building the `device' register.
330023 //
330024 device = 0;
330025 //
330026 // The access will be LBA: no CHS at all here!
330027 //
330028 device |= ATA_DEVICE_LBA;
330029 //
330030 // Set the device number, relative to the bus.
330031 //
330032 device |= ata_table[drive].target;
330033 //
330034 // Put the highest four bits of the sector number,
330035 // that can use at most 28 bits.
330036 //
330037 device |= ((sector & 0x0F000000) >> 24);
330038 //
330039 // Must select the new drive.
330040 //
330041 out_8 (ata_table[drive].r_device, device);
330042 //
330043 // Wait for selected drive ready.
330044 //
330045 s = ata_rdy (drive, ATA_TIMEOUT);
330046 if (s < 0)
330047 {
330048 errset (errno);
330049 return (-1);
330050 }
330051 //
330052 // Ok.
330053 //
330054 return (0);
330055 }
|
|
94.4.8
kernel/driver/ata/ata_drq.c
Si veda la sezione 93.2.
340001 #include <kernel/driver/ata.h>
340002 #include <kernel/lib_s.h>
340003 #include <kernel/ibm_i386.h>
340004 #include <stdint.h>
340005 #include <errno.h>
340006 //----------------------------------------------------------
340007 int
340008 ata_drq (int drive, clock_t timeout)
340009 {
340010 clock_t time_start;
340011 clock_t time_now;
340012 clock_t time_elapsed;
340013 int status;
340014 //
340015 // The timeout value must be at least two.
340016 //
340017 if (timeout < 2)
340018 {
340019 timeout = 2;
340020 }
340021 //
340022 // Get the status register.
340023 //
340024 time_elapsed = 0;
340025 time_start = s_clock ((pid_t) 0);
340026 while (time_elapsed < timeout)
340027 {
340028 time_now = s_clock ((pid_t) 0);
340029 time_elapsed = time_now - time_start;
340030 //
340031 status = in_8 (ata_table[drive].r_status);
340032 //
340033 // Is it BSY?
340034 //
340035 if (status & ATA_STATUS_BSY)
340036 {
340037 //
340038 // Read the status again.
340039 //
340040 continue;
340041 }
340042 //
340043 // No more busy, but check for errors.
340044 //
340045 if (status & ATA_STATUS_DF)
340046 {
340047 k_printf ("[%s] ERROR: drive %i fault\n",
340048 __func__, drive);
340049 ata_reset (drive);
340050 errset (E_HARDWARE_FAULT);
340051 return (-1);
340052 }
340053 //
340054 if (status & ATA_STATUS_ERR)
340055 {
340056 k_printf ("[%s] ERROR: drive %i error\n",
340057 __func__, drive);
340058 ata_reset (drive);
340059 errset (E_DRIVER_FAULT);
340060 return (-1);
340061 }
340062 //
340063 // Now check for the DRQ.
340064 //
340065 if (status & ATA_STATUS_DRQ)
340066 {
340067 //
340068 // Ok.
340069 //
340070 return (0);
340071 }
340072 }
340073 //
340074 // Sorry: time out!
340075 //
340076 k_printf ("[%s] ERROR: drive %i timeout\n", __func__,
340077 drive);
340078 errset (ETIME);
340079 return (-1);
340080 }
|
|
94.4.9
kernel/driver/ata/ata_init.c
Si veda la sezione 93.2.
350001 #include <kernel/driver/ata.h>
350002 #include <kernel/lib_k.h>
350003 #include <kernel/ibm_i386.h>
350004 #include <stdint.h>
350005 #include <errno.h>
350006 //----------------------------------------------------------
350007 void
350008 ata_init (void)
350009 {
350010 unsigned char status;
350011 int s;
350012 int d;
350013 //
350014 // Set bus numbers and I/O ports for each possible
350015 // drive.
350016 // I/O ports are related to the bus, so every couple
350017 // of
350018 // drive has the same ports.
350019 //
350020 if (ATA_MAX_DEVICES > 0)
350021 {
350022 ata_table[0].bus = 0;
350023 ata_table[0].r_data = ATA0_DATA;
350024 ata_table[0].r_feature = ATA0_FEATURE;
350025 ata_table[0].r_error = ATA0_ERROR;
350026 ata_table[0].r_count = ATA0_COUNT;
350027 ata_table[0].r_low = ATA0_LOW;
350028 ata_table[0].r_mid = ATA0_MID;
350029 ata_table[0].r_high = ATA0_HIGH;
350030 ata_table[0].r_device = ATA0_DEVICE;
350031 ata_table[0].r_command = ATA0_COMMAND;
350032 ata_table[0].r_status = ATA0_STATUS;
350033 ata_table[0].r_control = ATA0_CONTROL;
350034 ata_table[0].r_alternate = ATA0_ALTERNATE;
350035 ata_table[0].target = ATA_DEVICE_MASTER;
350036 //
350037 ata_table[1].bus = 0;
350038 ata_table[1].r_data = ATA0_DATA;
350039 ata_table[1].r_feature = ATA0_FEATURE;
350040 ata_table[1].r_error = ATA0_ERROR;
350041 ata_table[1].r_count = ATA0_COUNT;
350042 ata_table[1].r_low = ATA0_LOW;
350043 ata_table[1].r_mid = ATA0_MID;
350044 ata_table[1].r_high = ATA0_HIGH;
350045 ata_table[1].r_device = ATA0_DEVICE;
350046 ata_table[1].r_command = ATA0_COMMAND;
350047 ata_table[1].r_status = ATA0_STATUS;
350048 ata_table[1].r_control = ATA0_CONTROL;
350049 ata_table[1].r_alternate = ATA0_ALTERNATE;
350050 ata_table[1].target = ATA_DEVICE_SLAVE;
350051 }
350052 //
350053 if (ATA_MAX_DEVICES > 2)
350054 {
350055 ata_table[2].bus = 1;
350056 ata_table[2].r_data = ATA1_DATA;
350057 ata_table[2].r_feature = ATA1_FEATURE;
350058 ata_table[2].r_error = ATA1_ERROR;
350059 ata_table[2].r_count = ATA1_COUNT;
350060 ata_table[2].r_low = ATA1_LOW;
350061 ata_table[2].r_mid = ATA1_MID;
350062 ata_table[2].r_high = ATA1_HIGH;
350063 ata_table[2].r_device = ATA1_DEVICE;
350064 ata_table[2].r_command = ATA1_COMMAND;
350065 ata_table[2].r_status = ATA1_STATUS;
350066 ata_table[2].r_control = ATA1_CONTROL;
350067 ata_table[2].r_alternate = ATA1_ALTERNATE;
350068 ata_table[2].target = ATA_DEVICE_MASTER;
350069 //
350070 ata_table[3].bus = 1;
350071 ata_table[3].r_data = ATA1_DATA;
350072 ata_table[3].r_feature = ATA1_FEATURE;
350073 ata_table[3].r_error = ATA1_ERROR;
350074 ata_table[3].r_count = ATA1_COUNT;
350075 ata_table[3].r_low = ATA1_LOW;
350076 ata_table[3].r_mid = ATA1_MID;
350077 ata_table[3].r_high = ATA1_HIGH;
350078 ata_table[3].r_device = ATA1_DEVICE;
350079 ata_table[3].r_command = ATA1_COMMAND;
350080 ata_table[3].r_status = ATA1_STATUS;
350081 ata_table[3].r_control = ATA1_CONTROL;
350082 ata_table[3].r_alternate = ATA1_ALTERNATE;
350083 ata_table[3].target = ATA_DEVICE_SLAVE;
350084 }
350085 //
350086 if (ATA_MAX_DEVICES > 4)
350087 {
350088 ata_table[4].bus = 2;
350089 ata_table[4].r_data = ATA2_DATA;
350090 ata_table[4].r_feature = ATA2_FEATURE;
350091 ata_table[4].r_error = ATA2_ERROR;
350092 ata_table[4].r_count = ATA2_COUNT;
350093 ata_table[4].r_low = ATA2_LOW;
350094 ata_table[4].r_mid = ATA2_MID;
350095 ata_table[4].r_high = ATA2_HIGH;
350096 ata_table[4].r_device = ATA2_DEVICE;
350097 ata_table[4].r_command = ATA2_COMMAND;
350098 ata_table[4].r_status = ATA2_STATUS;
350099 ata_table[4].r_control = ATA2_CONTROL;
350100 ata_table[4].r_alternate = ATA2_ALTERNATE;
350101 ata_table[4].target = ATA_DEVICE_MASTER;
350102 //
350103 ata_table[5].bus = 2;
350104 ata_table[5].r_data = ATA2_DATA;
350105 ata_table[5].r_feature = ATA2_FEATURE;
350106 ata_table[5].r_error = ATA2_ERROR;
350107 ata_table[5].r_count = ATA2_COUNT;
350108 ata_table[5].r_low = ATA2_LOW;
350109 ata_table[5].r_mid = ATA2_MID;
350110 ata_table[5].r_high = ATA2_HIGH;
350111 ata_table[5].r_device = ATA2_DEVICE;
350112 ata_table[5].r_command = ATA2_COMMAND;
350113 ata_table[5].r_status = ATA2_STATUS;
350114 ata_table[5].r_control = ATA2_CONTROL;
350115 ata_table[5].r_alternate = ATA2_ALTERNATE;
350116 ata_table[5].target = ATA_DEVICE_SLAVE;
350117 }
350118 //
350119 if (ATA_MAX_DEVICES > 6)
350120 {
350121 ata_table[6].bus = 3;
350122 ata_table[6].r_data = ATA3_DATA;
350123 ata_table[6].r_feature = ATA3_FEATURE;
350124 ata_table[6].r_error = ATA3_ERROR;
350125 ata_table[6].r_count = ATA3_COUNT;
350126 ata_table[6].r_low = ATA3_LOW;
350127 ata_table[6].r_mid = ATA3_MID;
350128 ata_table[6].r_high = ATA3_HIGH;
350129 ata_table[6].r_device = ATA3_DEVICE;
350130 ata_table[6].r_command = ATA3_COMMAND;
350131 ata_table[6].r_status = ATA3_STATUS;
350132 ata_table[6].r_control = ATA3_CONTROL;
350133 ata_table[6].r_alternate = ATA3_ALTERNATE;
350134 ata_table[6].target = ATA_DEVICE_MASTER;
350135 //
350136 ata_table[7].bus = 3;
350137 ata_table[7].r_data = ATA3_DATA;
350138 ata_table[7].r_feature = ATA3_FEATURE;
350139 ata_table[7].r_error = ATA3_ERROR;
350140 ata_table[7].r_count = ATA3_COUNT;
350141 ata_table[7].r_low = ATA3_LOW;
350142 ata_table[7].r_mid = ATA3_MID;
350143 ata_table[7].r_high = ATA3_HIGH;
350144 ata_table[7].r_device = ATA3_DEVICE;
350145 ata_table[7].r_command = ATA3_COMMAND;
350146 ata_table[7].r_status = ATA3_STATUS;
350147 ata_table[7].r_control = ATA3_CONTROL;
350148 ata_table[7].r_alternate = ATA3_ALTERNATE;
350149 ata_table[7].target = ATA_DEVICE_SLAVE;
350150 }
350151 //
350152 // Scan and eliminate buses with no drive at all.
350153 //
350154 for (d = 0; d < ATA_MAX_DEVICES; d += 2)
350155 {
350156 status = in_8 (ata_table[d].r_status);
350157 if (status == 0xFF)
350158 {
350159 ata_table[d].present = 0;
350160 ata_table[d + 1].present = 0;
350161 }
350162 else
350163 {
350164 ata_table[d].present = 1;
350165 ata_table[d + 1].present = 1;
350166 }
350167 }
350168 //
350169 // Identify drives.
350170 //
350171 for (d = 0; d < ATA_MAX_DEVICES; d++)
350172 {
350173 if (ata_table[d].present == 0)
350174 {
350175 continue;
350176 }
350177 //
350178 // Register `device'.
350179 //
350180 s = ata_device (d, 0);
350181 if (s < 0)
350182 {
350183 errset (errno);
350184 k_perror (NULL);
350185 ata_table[d].present = 0;
350186 continue;
350187 }
350188 //
350189 // Send command `IDENTIFY DEVICE'
350190 //
350191 s =
350192 ata_cmd_identify_device (d, &(ata_table[d].id[0]));
350193 if (s < 0)
350194 {
350195 ata_table[d].present = 0;
350196 continue;
350197 }
350198 //
350199 // Verify again if the drive is present: the
350200 // function might have found that it does not
350201 // exist.
350202 //
350203 if (ata_table[d].present == 0)
350204 {
350205 continue;
350206 }
350207 //
350208 // Find total sectors (for 28 bit LBA access).
350209 // It is written
350210 // inside the integer formed by `identity[60]'
350211 // and
350212 // `identity[61]', considering it in little
350213 // endian mode.
350214 // It is taken the pointer to `identity[60]',
350215 // transformed
350216 // into a pointer to a 32 bit integer, and then
350217 // dereferenced
350218 // again.
350219 //
350220 ata_table[d].sectors
350221 = *((uint32_t *) & (ata_table[d].id[60]));
350222 //
350223 // Check if the size value is right.
350224 //
350225 if (ata_table[d].sectors == 0)
350226 {
350227 ata_table[d].present = 0;
350228 }
350229 else
350230 {
350231 //
350232 // Show info.
350233 //
350234 k_printf ("[%s] ATA drive %i size %i Kib\n",
350235 __func__, d, ata_table[d].sectors / 2);
350236 }
350237 }
350238 }
|
|
94.4.10
kernel/driver/ata/ata_lba28.c
Si veda la sezione 93.2.
360001 #include <kernel/driver/ata.h>
360002 #include <kernel/lib_s.h>
360003 #include <kernel/ibm_i386.h>
360004 #include <stdint.h>
360005 #include <errno.h>
360006 //----------------------------------------------------------
360007 int
360008 ata_lba28 (int drive, unsigned int sector,
360009 unsigned char count)
360010 {
360011 int s;
360012 unsigned char low;
360013 unsigned char mid;
360014 unsigned char high;
360015 //
360016 // Register `device'.
360017 //
360018 s = ata_device (drive, sector);
360019 if (s < 0)
360020 {
360021 k_perror (NULL);
360022
360023 errset (errno);
360024 return (-1);
360025 }
360026 //
360027 // Register `control', to set nIEN.
360028 //
360029 out_8 (ata_table[drive].r_control, ATA_CONTROL_NIEN);
360030 //
360031 // Register `feature'. not used.
360032 //
360033 out_8 (ata_table[drive].r_feature, 0);
360034 //
360035 // Register `count'
360036 //
360037 out_8 (ata_table[drive].r_count, count);
360038 //
360039 // Registers `low', `mid', `high'.
360040 //
360041 low = (sector & 0x000000FF);
360042 mid = ((sector & 0x0000FF00) >> 8);
360043 high = ((sector & 0x00FF0000) >> 16);
360044 //
360045 out_8 (ata_table[drive].r_low, low);
360046 out_8 (ata_table[drive].r_mid, mid);
360047 out_8 (ata_table[drive].r_high, high);
360048 //
360049 // Ok.
360050 //
360051 return (0);
360052 }
|
|
94.4.11
kernel/driver/ata/ata_public.c
Si veda la sezione 93.2.
370001 #include <kernel/driver/ata.h>
370002 //----------------------------------------------------------
370003 ata_t ata_table[ATA_MAX_DEVICES];
370004 //----------------------------------------------------------
|
|
94.4.12
kernel/driver/ata/ata_rdy.c
Si veda la sezione 93.2.
380001 #include <kernel/driver/ata.h>
380002 #include <kernel/lib_s.h>
380003 #include <kernel/ibm_i386.h>
380004 #include <stdint.h>
380005 #include <errno.h>
380006 //----------------------------------------------------------
380007 int
380008 ata_rdy (int drive, clock_t timeout)
380009 {
380010 clock_t time_start;
380011 clock_t time_now;
380012 clock_t time_elapsed;
380013 unsigned char status;
380014 //
380015 // The timeout value must be at least two.
380016 //
380017 if (timeout < 2)
380018 {
380019 timeout = 2;
380020 }
380021 //
380022 // Get the status register.
380023 //
380024 time_elapsed = 0;
380025 time_start = s_clock ((pid_t) 0);
380026 while (time_elapsed < timeout)
380027 {
380028 time_now = s_clock ((pid_t) 0);
380029 time_elapsed = time_now - time_start;
380030 //
380031 status = in_8 (ata_table[drive].r_status);
380032 //
380033 // Is it BSY?
380034 //
380035 if (status & ATA_STATUS_BSY)
380036 {
380037 //
380038 // Read the status again.
380039 //
380040 continue;
380041 }
380042 //
380043 // No more busy, but check for errors.
380044 //
380045 if (status & ATA_STATUS_DF)
380046 {
380047 k_printf ("[%s] ERROR: drive %i fault\n",
380048 __func__, drive);
380049 ata_reset (drive);
380050 errset (E_HARDWARE_FAULT);
380051 return (-1);
380052 }
380053 //
380054 if (status & ATA_STATUS_ERR)
380055 {
380056 k_printf ("[%s] ERROR: drive %i error\n",
380057 __func__, drive);
380058 ata_reset (drive);
380059 errset (E_DRIVER_FAULT);
380060 return (-1);
380061 }
380062 //
380063 // Otherwise: ok.
380064 //
380065 return (0);
380066 }
380067 //
380068 // Sorry: time out!
380069 //
380070 k_printf ("[%s] ERROR: drive %i timeout\n", __func__,
380071 drive);
380072 errset (ETIME);
380073 return (-1);
380074 }
|
|
94.4.13
kernel/driver/ata/ata_reset.c
Si veda la sezione 93.2.
390001 #include <kernel/driver/ata.h>
390002 #include <kernel/lib_s.h>
390003 #include <kernel/ibm_i386.h>
390004 #include <stdint.h>
390005 #include <errno.h>
390006 //----------------------------------------------------------
390007 void
390008 ata_reset (int drive)
390009 {
390010 out_8 (ata_table[drive].r_control, ATA_CONTROL_SRST);
390011 out_8 (ata_table[drive].r_control, 0);
390012 }
|
|
94.4.14
kernel/driver/ata/ata_valid.c
Si veda la sezione 93.2.
400001 #include <kernel/driver/ata.h>
400002 #include <errno.h>
400003 //----------------------------------------------------------
400004 int
400005 ata_valid (int drive)
400006 {
400007 //
400008 // Verify if `drive' argument is possible.
400009 //
400010 if (drive < 0 || drive >= ATA_MAX_DEVICES)
400011 {
400012 errset (EINVAL);
400013 return (-1);
400014 }
400015 //
400016 // Verify if `drive' is present at the moment.
400017 //
400018 if (ata_table[drive].present == 0)
400019 {
400020 errset (E_NO_MEDIUM);
400021 return (-1);
400022 }
400023 //
400024 // OK.
400025 //
400026 return (0);
400027 }
|
|
94.4.15
kernel/driver/kbd.h
Si veda la sezione 93.10.
410001 #ifndef _KERNEL_DRIVER_KBD_H
410002 #define _KERNEL_DRIVER_KBD_H 1
410003 //----------------------------------------------------------
410004 #include <stdbool.h>
410005 //----------------------------------------------------------
410006 //
410007 // Keyboard status.
410008 //
410009 typedef struct
410010 {
410011 bool shift;
410012 bool shift_lock;
410013 bool ctrl;
410014 bool alt;
410015 bool echo;
410016 unsigned char key;
410017 unsigned char map1[128];
410018 unsigned char map2[128];
410019 } kbd_t;
410020 //
410021 extern kbd_t kbd;
410022 //----------------------------------------------------------
410023 void kbd_load (void);
410024 void kbd_isr (void);
410025 //----------------------------------------------------------
410026 #endif
|
|
94.4.16
kernel/driver/kbd/kbd_isr.c
Si veda la sezione 93.10.
420001 #include <kernel/driver/kbd.h>
420002 #include <kernel/ibm_i386.h>
420003 //----------------------------------------------------------
420004 void
420005 kbd_isr (void)
420006 {
420007 //
420008 // Get a character from the keyboard channel.
420009 //
420010 unsigned char scancode = (int) in_8 (0x60);
420011 //
420012 // Check for [Shift], [Shift-Lock], [Ctrl] and [Alt]
420013 // keys.
420014 //
420015 switch (scancode)
420016 {
420017 case 0x2A:
420018 kbd.shift = 1;
420019 break;
420020 case 0x36:
420021 kbd.shift = 1;
420022 break;
420023 case 0xAA:
420024 kbd.shift = 0;
420025 break;
420026 case 0xB6:
420027 kbd.shift = 0;
420028 break;
420029 case 0x1D:
420030 kbd.ctrl = 1;
420031 break;
420032 case 0x9D:
420033 kbd.ctrl = 0;
420034 break;
420035 case 0x38:
420036 kbd.alt = 1;
420037 break;
420038 case 0xB8:
420039 kbd.alt = 0;
420040 break;
420041 case 0x3A:
420042 kbd.shift_lock = !kbd.shift_lock;
420043 break;
420044 }
420045 //
420046 // Check for usual keys, but only if `kbd.key' is
420047 // currently empty.
420048 //
420049 if (scancode <= 127 && kbd.ctrl && kbd.key == 0)
420050 {
420051 //
420052 // Something was pressed, combined with [Ctrl].
420053 //
420054 switch (kbd.map1[scancode])
420055 {
420056 case 'a':
420057 kbd.key = 0x01;
420058 break; // SOH
420059 case 'b':
420060 kbd.key = 0x02;
420061 break; // STX
420062 case 'c':
420063 kbd.key = 0x03;
420064 break; // ETX
420065 case 'd':
420066 kbd.key = 0x04;
420067 break; // EOT
420068 case 'e':
420069 kbd.key = 0x05;
420070 break; // ENQ
420071 case 'f':
420072 kbd.key = 0x06;
420073 break; // ACK
420074 case 'g':
420075 kbd.key = 0x07;
420076 break; // BEL
420077 case 'h':
420078 kbd.key = 0x08;
420079 break; // BS
420080 case 'i':
420081 kbd.key = 0x09;
420082 break; // HT
420083 case 'j':
420084 kbd.key = 0x0A;
420085 break; // LF
420086 case 'k':
420087 kbd.key = 0x0B;
420088 break; // VT
420089 case 'l':
420090 kbd.key = 0x0C;
420091 break; // FF
420092 case 'm':
420093 kbd.key = 0x0D;
420094 break; // CR
420095 case 'n':
420096 kbd.key = 0x0E;
420097 break; // SO
420098 case 'o':
420099 kbd.key = 0x0F;
420100 break; // SI
420101 case 'p':
420102 kbd.key = 0x10;
420103 break; // DLE
420104 case 'q':
420105 kbd.key = 0x11;
420106 break; // DC1
420107 case 'r':
420108 kbd.key = 0x12;
420109 break; // DC2
420110 case 's':
420111 kbd.key = 0x13;
420112 break; // DC3
420113 case 't':
420114 kbd.key = 0x14;
420115 break; // DC4
420116 case 'u':
420117 kbd.key = 0x15;
420118 break; // NAK
420119 case 'v':
420120 kbd.key = 0x16;
420121 break; // SYN
420122 case 'w':
420123 kbd.key = 0x17;
420124 break; // ETB
420125 case 'x':
420126 kbd.key = 0x18;
420127 break; // CAN
420128 case 'y':
420129 kbd.key = 0x19;
420130 break; // EM
420131 case 'z':
420132 kbd.key = 0x1A;
420133 break; // SUB
420134 case '[':
420135 kbd.key = 0x1B;
420136 break; // ESC
420137 case '\\':
420138 kbd.key = 0x1C;
420139 break; // FS
420140 case ']':
420141 kbd.key = 0x1D;
420142 break; // GS
420143 case '^':
420144 kbd.key = 0x1E;
420145 break; // RS
420146 case '_':
420147 kbd.key = 0x1F;
420148 break; // US
420149 }
420150 }
420151 else if (scancode <= 127 && kbd.key == 0
420152 && kbd.map1[scancode] != 0)
420153 {
420154 //
420155 // Something was pressed, but no [Ctrl] is
420156 // there.
420157 //
420158 if (kbd.shift || kbd.shift_lock)
420159 {
420160 kbd.key = kbd.map2[scancode];
420161 }
420162 else
420163 {
420164 kbd.key = kbd.map1[scancode];
420165 }
420166 }
420167 }
|
|
94.4.17
kernel/driver/kbd/kbd_load.c
Si veda la sezione 93.10.
430001 #include <kernel/driver/kbd.h>
430002 //----------------------------------------------------------
430003 void
430004 kbd_load (void)
430005 {
430006 int i;
430007 //
430008 // Reset the map.
430009 //
430010 for (i = 0; i <= 127; i++)
430011 {
430012 kbd.map1[i] = 0;
430013 kbd.map2[i] = 0;
430014 }
430015 //
430016 // Association for an italian map, but only with
430017 // ASCII characters
430018 // (there are no accented letters).
430019 //
430020 kbd.map1[1] = 27;
430021 kbd.map2[1] = 27; // ESC
430022 kbd.map1[2] = '1';
430023 kbd.map2[2] = '!';
430024 kbd.map1[3] = '2';
430025 kbd.map2[3] = '"';
430026 kbd.map1[4] = '3';
430027 kbd.map2[4] = 'L'; // 3, £
430028 kbd.map1[5] = '4';
430029 kbd.map2[5] = '$';
430030 kbd.map1[6] = '5';
430031 kbd.map2[6] = '%';
430032 kbd.map1[7] = '6';
430033 kbd.map2[7] = '&';
430034 kbd.map1[8] = '7';
430035 kbd.map2[8] = '/';
430036 kbd.map1[9] = '8';
430037 kbd.map2[9] = '(';
430038 kbd.map1[10] = '9';
430039 kbd.map2[10] = ')';
430040 kbd.map1[11] = '0';
430041 kbd.map2[11] = '=';
430042 kbd.map1[12] = '\'';
430043 kbd.map2[12] = '?';
430044 kbd.map1[13] = 'i';
430045 kbd.map2[13] = '^'; // ì, ^
430046 kbd.map1[14] = '\b';
430047 kbd.map2[14] = '\b'; // Backspace
430048 kbd.map1[15] = '\t';
430049 kbd.map2[15] = '\t';
430050 kbd.map1[16] = 'q';
430051 kbd.map2[16] = 'Q';
430052 kbd.map1[17] = 'w';
430053 kbd.map2[17] = 'W';
430054 kbd.map1[18] = 'e';
430055 kbd.map2[18] = 'E';
430056 kbd.map1[19] = 'r';
430057 kbd.map2[19] = 'R';
430058 kbd.map1[20] = 't';
430059 kbd.map2[20] = 'T';
430060 kbd.map1[21] = 'y';
430061 kbd.map2[21] = 'Y';
430062 kbd.map1[22] = 'u';
430063 kbd.map2[22] = 'U';
430064 kbd.map1[23] = 'i';
430065 kbd.map2[23] = 'I';
430066 kbd.map1[24] = 'o';
430067 kbd.map2[24] = 'O';
430068 kbd.map1[25] = 'p';
430069 kbd.map2[25] = 'P';
430070 kbd.map1[26] = '[';
430071 kbd.map2[26] = '{'; // è, é
430072 kbd.map1[27] = ']';
430073 kbd.map2[27] = '}'; // +, *
430074 kbd.map1[28] = '\n';
430075 kbd.map2[28] = '\n'; // Enter
430076 kbd.map1[30] = 'a';
430077 kbd.map2[30] = 'A';
430078 kbd.map1[31] = 's';
430079 kbd.map2[31] = 'S';
430080 kbd.map1[32] = 'd';
430081 kbd.map2[32] = 'D';
430082 kbd.map1[33] = 'f';
430083 kbd.map2[33] = 'F';
430084 kbd.map1[34] = 'g';
430085 kbd.map2[34] = 'G';
430086 kbd.map1[35] = 'h';
430087 kbd.map2[35] = 'H';
430088 kbd.map1[36] = 'j';
430089 kbd.map2[36] = 'J';
430090 kbd.map1[37] = 'k';
430091 kbd.map2[37] = 'K';
430092 kbd.map1[38] = 'l';
430093 kbd.map2[38] = 'L';
430094 kbd.map1[39] = '@';
430095 kbd.map2[39] = '@'; // ò, ç
430096 kbd.map1[40] = '#';
430097 kbd.map2[40] = '#'; // à, °
430098 kbd.map1[41] = '\\';
430099 kbd.map2[41] = '|';
430100 kbd.map1[43] = 'u';
430101 kbd.map2[43] = 'U'; // ù, §
430102 kbd.map1[44] = 'z';
430103 kbd.map2[44] = 'Z';
430104 kbd.map1[45] = 'x';
430105 kbd.map2[45] = 'X';
430106 kbd.map1[46] = 'c';
430107 kbd.map2[46] = 'C';
430108 kbd.map1[47] = 'v';
430109 kbd.map2[47] = 'V';
430110 kbd.map1[48] = 'b';
430111 kbd.map2[48] = 'B';
430112 kbd.map1[49] = 'n';
430113 kbd.map2[49] = 'N';
430114 kbd.map1[50] = 'm';
430115 kbd.map2[50] = 'M';
430116 kbd.map1[51] = ',';
430117 kbd.map2[51] = ';';
430118 kbd.map1[52] = '.';
430119 kbd.map2[52] = ':';
430120 kbd.map1[53] = '-';
430121 kbd.map2[53] = '_';
430122 kbd.map1[56] = '<';
430123 kbd.map2[56] = '>';
430124 kbd.map1[57] = ' ';
430125 kbd.map2[57] = ' ';
430126 //
430127 kbd.map1[55] = '*';
430128 kbd.map2[55] = '*';
430129 kbd.map1[71] = '7';
430130 kbd.map2[71] = '7';
430131 kbd.map1[72] = '8';
430132 kbd.map2[72] = '8';
430133 kbd.map1[73] = '9';
430134 kbd.map2[73] = '9';
430135 kbd.map1[74] = '-';
430136 kbd.map2[74] = '-';
430137 kbd.map1[75] = '4';
430138 kbd.map2[75] = '4';
430139 kbd.map1[76] = '5';
430140 kbd.map2[76] = '5';
430141 kbd.map1[77] = '6';
430142 kbd.map2[77] = '6';
430143 kbd.map1[78] = '+';
430144 kbd.map2[78] = '+';
430145 kbd.map1[79] = '1';
430146 kbd.map2[79] = '1';
430147 kbd.map1[80] = '2';
430148 kbd.map2[80] = '2';
430149 kbd.map1[81] = '3';
430150 kbd.map2[81] = '3';
430151 kbd.map1[82] = '0';
430152 kbd.map2[82] = '0';
430153 kbd.map1[83] = '.';
430154 kbd.map2[83] = '.';
430155 kbd.map1[92] = '/';
430156 kbd.map2[92] = '/';
430157 kbd.map1[96] = '\n';
430158 kbd.map2[96] = '\n'; // Enter
430159 }
|
|
94.4.18
kernel/driver/kbd/kbd_public.c
Si veda la sezione 93.10.
440001 #include <kernel/driver/kbd.h>
440002 //----------------------------------------------------------
440003 kbd_t kbd;
|
|
94.4.19
kernel/driver/nic/ne2k.h
Si veda la sezione 93.16.
450001 #ifndef _KERNEL_DRIVER_NIC_NE2K_H
450002 #define _KERNEL_DRIVER_NIC_NE2K_H 1
450003 //----------------------------------------------------------
450004 #include <stdint.h>
450005 #include <sys/types.h>
450006 #include <unistd.h>
450007 #include <time.h>
450008 //----------------------------------------------------------
450009 //
450010 // Command register, available on all pages.
450011 //
450012 #define NE2K_CR 0x00 // rw
450013 //
450014 // Page 0 registers
450015 //
450016 #define NE2K_CLDA0 0x01 // r-
450017 #define NE2K_PSTART 0x01 // -w
450018 #define NE2K_CLDA1 0x02 // r-
450019 #define NE2K_PSTOP 0x02 // -w
450020 #define NE2K_BNRY 0x03 // rw
450021 #define NE2K_TSR 0x04 // r-
450022 #define NE2K_TPSR 0x04 // -w
450023 #define NE2K_NCR 0x05 // r-
450024 #define NE2K_TBCR0 0x05 // -w
450025 #define NE2K_FIFO 0x06 // r-
450026 #define NE2K_TBCR1 0x06 // -w
450027 #define NE2K_ISR 0x07 // rw
450028 #define NE2K_CRDA0 0x08 // r-
450029 #define NE2K_RSAR0 0x08 // -w
450030 #define NE2K_CRDA1 0x09 // r-
450031 #define NE2K_RSAR1 0x09 // -w
450032 #define NE2K_RBCR0 0x0A // -w
450033 #define NE2K_RBCR1 0x0B // -w
450034 #define NE2K_RSR 0x0C // r-
450035 #define NE2K_RCR 0x0C // -w
450036 #define NE2K_CNTR0 0x0D // r-
450037 #define NE2K_TCR 0x0D // -w
450038 #define NE2K_CNTR1 0x0E // r-
450039 #define NE2K_DCR 0x0E // -w
450040 #define NE2K_CNTR2 0x0F // r-
450041 #define NE2K_IMR 0x0F // -w
450042 //
450043 // Page 1 registers: all read and write
450044 //
450045 #define NE2K_PAR0 0x01 // rw
450046 #define NE2K_PAR1 0x02 // rw
450047 #define NE2K_PAR2 0x03 // rw
450048 #define NE2K_PAR3 0x04 // rw
450049 #define NE2K_PAR4 0x05 // rw
450050 #define NE2K_PAR5 0x06 // rw
450051 #define NE2K_CURR 0x07 // rw
450052 #define NE2K_MAR0 0x08 // rw
450053 #define NE2K_MAR1 0x09 // rw
450054 #define NE2K_MAR2 0x0A // rw
450055 #define NE2K_MAR3 0x0B // rw
450056 #define NE2K_MAR4 0x0C // rw
450057 #define NE2K_MAR5 0x0D // rw
450058 #define NE2K_MAR6 0x0E // rw
450059 #define NE2K_MAR7 0x0F // rw
450060 //
450061 // Page 2 registers: read version of the same registers
450062 // inside page 1:
450063 //
450064 // NE2K_PSTART 0x01 // -w
450065 // NE2K_PSTOP 0x02 // -w
450066 // -- 0x03
450067 // NE2K_TPSR 0x04 // -w
450068 // -- 0x05
450069 // -- 0x06
450070 // -- 0x07
450071 // -- 0x08
450072 // -- 0x09
450073 // -- 0x0A
450074 // -- 0x0B
450075 // NE2K_RCR 0x0C // -w
450076 // NE2K_TCR 0x0D // -w
450077 // NE2K_DCR 0x0E // -w
450078 // NE2K_IMR 0x0F // -w
450079 //
450080 // Extra registers, outside pages.
450081 //
450082 #define NE2K_DATA 0x10 // Data port.
450083 #define NE2K_RESET 0x1f // Reset port.
450084 //
450085 // DMA buffer structure.
450086 //
450087 // 0x0000 .--------------------------.
450088 // | |
450089 // | |
450090 // | ??? |
450091 // | |
450092 // | |
450093 // 0x4000 |--------------------------|
450094 // | transmit buffer ring [1] |
450095 // 0x4600 |--------------------------|
450096 // | |
450097 // | receive buffer ring |
450098 // | |
450099 // 0xC000 |--------------------------|
450100 // | |
450101 // | ??? |
450102 // | |
450103 // | |
450104 // `--------------------------' 0xFFFF
450105 //
450106 // [1] 0x600 is equal to 1536, that is the max space
450107 // that a packet can occupy inside the ring buffer.
450108 // So, there is the place for a
450109 // single transmission packet.
450110 //
450111 // Local DMA addresses:
450112 //
450113 #define NE2K_TX_START 0x40 // Means: 0x4000
450114 #define NE2K_TX_STOP 0x46 // Means: 0x4600
450115
450116 #define NE2K_RX_START 0x46 // Means: 0x4600
450117 #define NE2K_RX_STOP 0xC0 // Means: 0xC000
450118 //
450119 // Transmit buffer (remote DMA).
450120 //
450121 #define NE2K_TX_BUFFER NE2K_TX_START
450122 //
450123 // SA-PROM (Station Address PROM) size
450124 //
450125 #define NE2K_SAPROM_SIZE 32 // 32 bytes
450126 //----------------------------------------------------------
450127 int ne2k_check (uintptr_t io);
450128 int ne2k_isr (uintptr_t io);
450129 int ne2k_isr_expect (uintptr_t io, unsigned int isr_expect);
450130 int ne2k_reset (uintptr_t io, void *address);
450131 int ne2k_rx (uintptr_t io);
450132 int ne2k_rx_reset (uintptr_t io);
450133 int ne2k_tx (uintptr_t io, void *buffer, size_t size);
450134 //
450135 void ne2k_test2 (int eth);
450136
450137
450138 //----------------------------------------------------------
450139 #endif
|
|
94.4.20
kernel/driver/nic/ne2k/ne2k_check.c
Si veda la sezione 93.16.
460001 #include <kernel/driver/nic/ne2k.h>
460002 #include <kernel/ibm_i386.h>
460003 #include <errno.h>
460004 //----------------------------------------------------------
460005 int
460006 ne2k_check (uintptr_t io)
460007 {
460008 int status;
460009 int reg_00;
460010 int reg_0d;
460011 //
460012 // Read and save the command register (CR, 0x00): if
460013 // it is really the
460014 // command register, should not be equal to 0xFF.
460015 //
460016 reg_00 = in_8 (io + NE2K_CR);
460017 if (reg_00 == 0xFF)
460018 {
460019 errset (E_DRIVER_FAULT);
460020 return (-1);
460021 }
460022 //
460023 // Command register (CR)
460024 // .-------------------------------.
460025 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
460026 // |-------------------------------|
460027 // | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0x61
460028 // `-------------------------------'
460029 // \___/ \_______/ |
460030 // | | STOP
460031 // | Abort/complete
460032 // | remote DMA
460033 // Register
460034 // page 1
460035 //
460036 // Stop and select page 1.
460037 //
460038 out_8 ((io + NE2K_CR), 0x61);
460039 //
460040 // Read, save and overwrite the register MAR5 (0x0D
460041 // at
460042 // page 1).
460043 //
460044 reg_0d = in_8 (io + NE2K_MAR5);
460045 out_8 (io + NE2K_MAR5, 0xFF);
460046 //
460047 // Command register (CR)
460048 // .-------------------------------.
460049 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
460050 // |-------------------------------|
460051 // | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0x21
460052 // `-------------------------------'
460053 // \___/ \_______/ |
460054 // | | STOP
460055 // | Abort/complete
460056 // | remote DMA
460057 // Register
460058 // page 0
460059 //
460060 // Stop and select page 0.
460061 //
460062 out_8 ((io + NE2K_CR), 0x21);
460063 //
460064 // Read the tally counter 0 (CNTR0) to clear it.
460065 //
460066 in_8 (io + NE2K_CNTR0);
460067 //
460068 // Now the tally counter 0 (CNTR0) should be zero.
460069 //
460070 status = in_8 (io + NE2K_CNTR0);
460071 if (status)
460072 {
460073 //
460074 // The value obtained is not zero, so it is not
460075 // a NE2000 nic and the page change had probably
460076 // no effect. So, restore the values found
460077 // inside
460078 // 0x00 and 0x0D, without trying to change page.
460079 //
460080 out_8 (io, reg_00);
460081 out_8 ((io + 0x0D), reg_0d);
460082 errset (E_DRIVER_FAULT);
460083 return (-1);
460084 }
460085 //
460086 // Everything is ok: it might be a NE2000 nic.
460087 //
460088 return (0);
460089 }
|
|
94.4.21
kernel/driver/nic/ne2k/ne2k_isr.c
Si veda la sezione 93.16.
470001 #include <kernel/driver/pci.h>
470002 #include <kernel/driver/nic/ne2k.h>
470003 #include <kernel/ibm_i386.h>
470004 #include <errno.h>
470005 #include <kernel/lib_k.h>
470006 #include <kernel/lib_s.h>
470007 //----------------------------------------------------------
470008 int
470009 ne2k_isr (uintptr_t io)
470010 {
470011 int isr;
470012 //
470013 // Get ISR (interrupt status register).
470014 //
470015 isr = in_8 (io + NE2K_ISR);
470016 //
470017 //
470018 //
470019 if (isr & 0x01)
470020 {
470021 //
470022 // Frame received.
470023 //
470024 out_8 (io + NE2K_ISR, 0x01);
470025 ne2k_rx (io);
470026 }
470027 if (isr & 0x04)
470028 {
470029 //
470030 // Frame received with errors.
470031 //
470032 out_8 (io + NE2K_ISR, 0x04);
470033 }
470034 if (isr & 0x02)
470035 {
470036 //
470037 // Frame sent correctly.
470038 //
470039 ;
470040 }
470041 if (isr & 0x08)
470042 {
470043 //
470044 // Frame sent with errors.
470045 //
470046 ;
470047 }
470048 if (isr & 0x10)
470049 {
470050 k_printf ("OVERWRITE\n");
470051 out_8 (io + NE2K_ISR, 0x10);
470052 //
470053 // I don't understand if it works: Bochs just
470054 // don't accept
470055 // frames if they can make an overflow.
470056 //
470057 ne2k_rx (io);
470058 ne2k_rx_reset (io);
470059 }
470060 if (isr & 0x20)
470061 {
470062 //
470063 // Counter overflow.
470064 //
470065 out_8 (io + NE2K_ISR, 0x20);
470066 }
470067 if (isr & 0x40)
470068 {
470069 //
470070 // Remote DMA complete.
470071 //
470072 ;
470073 }
470074 if (isr & 0x80)
470075 {
470076 //
470077 // Reset status.
470078 //
470079 ;
470080 }
470081 //
470082 // End.
470083 //
470084 return (0);
470085 }
|
|
94.4.22
kernel/driver/nic/ne2k/ne2k_isr_expect.c
Si veda la sezione 93.16.
480001 #include <kernel/driver/nic/ne2k.h>
480002 #include <kernel/ibm_i386.h>
480003 #include <kernel/lib_k.h>
480004 #include <errno.h>
480005 #include <unistd.h>
480006 #include <time.h>
480007 //----------------------------------------------------------
480008 #define DEBUG 0
480009 //----------------------------------------------------------
480010 int
480011 ne2k_isr_expect (uintptr_t io, unsigned int isr_expect)
480012 {
480013 int retry = 5;
480014 int status;
480015 //
480016 //
480017 //
480018 for (; retry > 0; retry--)
480019 {
480020 status = in_8 (io + NE2K_ISR);
480021 //
480022 if (status & isr_expect)
480023 {
480024 //
480025 // Reset the bit found true and exit loop.
480026 //
480027 out_8 ((io + NE2K_ISR), isr_expect);
480028 return (0);
480029 }
480030 }
480031 //
480032 // If ISR is zero, we assume that it is ok.
480033 //
480034 if (status == 0)
480035 {
480036 if (DEBUG)
480037 {
480038 k_printf ("[isr=0x%02x expect=0x%02x]",
480039 status, isr_expect);
480040 return (0);
480041 }
480042 return (0);
480043 }
480044 else
480045 {
480046 if (DEBUG)
480047 {
480048 //
480049 // It is not zero, but we prefer to let it
480050 // go...
480051 //
480052 k_printf ("[isr=0x%02x expect=0x%02x]",
480053 status, isr_expect);
480054 return (0);
480055 }
480056 else
480057 {
480058 errset (E_DRIVER_FAULT);
480059 return (-1);
480060 }
480061 }
480062 }
|
|
94.4.23
kernel/driver/nic/ne2k/ne2k_reset.c
Si veda la sezione 93.16.
490001 #include <kernel/driver/pci.h>
490002 #include <kernel/driver/nic/ne2k.h>
490003 #include <kernel/ibm_i386.h>
490004 #include <errno.h>
490005 #include <kernel/lib_k.h>
490006 #include <kernel/lib_s.h>
490007 //----------------------------------------------------------
490008 int
490009 ne2k_reset (uintptr_t io, void *address)
490010 {
490011 int status;
490012 int i;
490013 uint8_t sa_prom[NE2K_SAPROM_SIZE];
490014 uint8_t par[6];
490015 //
490016 // ---------------------------------------------------
490017 // RESET
490018 // ---------------------------------------------------
490019 //
490020 status = in_8 (io + NE2K_RESET);
490021 out_8 ((io + NE2K_RESET), 0xFF);
490022 out_8 ((io + NE2K_RESET), status);
490023 //
490024 // Interrupt status register (ISR)
490025 // .-------------------------------.
490026 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
490027 // |-------------------------------|
490028 // | 1 | ? | ? | ? | ? | ? | ? | ? | 0x80
490029 // `-------------------------------'
490030 // |
490031 // Reset status
490032 //
490033 // Verify to have reset the NIC.
490034 //
490035 status = ne2k_isr_expect (io, 0x80);
490036 if (status)
490037 {
490038 errset (errno);
490039 return (-1);
490040 }
490041 //
490042 // Reset all ISR register flags.
490043 //
490044 out_8 ((io + NE2K_ISR), 0xFF);
490045 //
490046 // ---------------------------------------------------
490047 // GET ETHERNET ADDRESS FROM SA-PROM (Station
490048 // Address PROM)
490049 // ---------------------------------------------------
490050 //
490051 // Command register (CR)
490052 // .-------------------------------.
490053 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
490054 // |-------------------------------|
490055 // | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0x21
490056 // `-------------------------------'
490057 // \_____/ \_________/ |
490058 // | | STOP
490059 // | |
490060 // | Abort/complete
490061 // | remote DMA
490062 // |
490063 // Register
490064 // page 0
490065 //
490066 out_8 ((io + NE2K_CR), 0x21);
490067 //
490068 // Interrupt status register (ISR)
490069 // .-------------------------------.
490070 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
490071 // |-------------------------------|
490072 // | 1 | ? | ? | ? | ? | ? | ? | ? | 0x80
490073 // `-------------------------------'
490074 // |
490075 // Reset status
490076 //
490077 // Verify to have reset the NIC.
490078 //
490079 status = ne2k_isr_expect (io, 0x80);
490080 if (status)
490081 {
490082 errset (errno);
490083 return (-1);
490084 }
490085 //
490086 // Data configuration register (DCR)
490087 // .-------------------------------.
490088 // | - |FT1|FT0|ARM| LS|LAS|BOS|WTS|
490089 // |-------------------------------|
490090 // | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0x48
490091 // `-------------------------------'
490092 // \_____/ : | : : :
490093 // | : | : : Byte DMA transfer
490094 // | : | : :
490095 // | : | : Little endian byte order
490096 // | : | :
490097 // | : | Dual 16 bit DMA mode
490098 // | : |
490099 // | : Loopback OFF (normal operation)
490100 // | :
490101 // | Send Command non executed: all frames removed
490102 // from
490103 // | Buffer Ring under program control
490104 // |
490105 // FIFO threshold 8 bytes
490106 //
490107 out_8 ((io + NE2K_DCR), 0x48);
490108 //
490109 // Reset remote byte count registers.
490110 //
490111 out_8 ((io + NE2K_RBCR0), 0x00);
490112 out_8 ((io + NE2K_RBCR1), 0x00);
490113 //
490114 // Disable interrupts with an empty mask.
490115 //
490116 out_8 ((io + NE2K_IMR), 0x00);
490117 //
490118 // Reset all ISR register flags.
490119 //
490120 out_8 ((io + NE2K_ISR), 0xFF);
490121 //
490122 // Receive configuration register (RCR)
490123 // .-------------------------------.
490124 // | - | - |MON|PRO| AM| AB| AR|SEP|
490125 // |-------------------------------|
490126 // | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0x20
490127 // `-------------------------------'
490128 // | : : : : :
490129 // | : : : : Frames with receive errors are
490130 // | : : : : rejected
490131 // | : : : :
490132 // | : : : Frames with fewer than 64 bytes rejected
490133 // | : : :
490134 // | : : Frames with broadcast destination rejected
490135 // | : : accepted
490136 // | : :
490137 // | : Frames with multicast destination address
490138 // | : not checked
490139 // | :
490140 // | Physical address of node must match the station
490141 // | address
490142 // |
490143 // Monitor mode: frames checked but not buffered to
490144 // memory
490145 //
490146 // Monitor mode.
490147 //
490148 out_8 ((io + NE2K_RCR), 0x20);
490149 //
490150 // Transmit configuration register (TCR)
490151 // .--------------------------------.
490152 // | - | - | - |OFST|ATD|LB1|LB0|CRC|
490153 // |--------------------------------|
490154 // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0x02
490155 // `--------------------------------'
490156 // \_____/ :
490157 // | CRC appended by the transmitter
490158 // |
490159 // Internal loopback (mode 1)
490160 //
490161 // [Loopback is not supported by Bochs]
490162 //
490163 // Transmit loopback.
490164 //
490165 out_8 ((io + NE2K_TCR), 0x02);
490166 //
490167 // Remote byte count registers to NE2K_SAPROM_SIZE:
490168 // the bytes to be
490169 // read from SA-PROM.
490170 //
490171 out_8 ((io + NE2K_RBCR0), NE2K_SAPROM_SIZE);
490172 out_8 ((io + NE2K_RBCR1), (NE2K_SAPROM_SIZE >> 8));
490173 //
490174 // Set the remote DMA address to zero.
490175 //
490176 out_8 ((io + NE2K_RSAR0), 0x00); // Must be
490177 // zero.
490178 out_8 ((io + NE2K_RSAR1), 0x00);
490179 //
490180 // Command register (CR)
490181 // .-------------------------------.
490182 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
490183 // |-------------------------------|
490184 // | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0x0A
490185 // `-------------------------------'
490186 // \___/ \_______/ |
490187 // | | START
490188 // | Read
490189 // |
490190 // Register
490191 // page 0
490192 //
490193 out_8 ((io + NE2K_CR), 0x0A);
490194 //
490195 // Save the SA-PROM content.
490196 //
490197 for (i = 0; i < NE2K_SAPROM_SIZE; i++)
490198 {
490199 sa_prom[i] = in_8 (io + NE2K_DATA);
490200 }
490201 //
490202 // Set NIC physical address from SA-PROM data.
490203 //
490204 par[0] = sa_prom[0];
490205 par[1] = sa_prom[2];
490206 par[2] = sa_prom[4];
490207 par[3] = sa_prom[6];
490208 par[4] = sa_prom[8];
490209 par[5] = sa_prom[10];
490210 //
490211 // Copy to the `address' pointer.
490212 //
490213 if (address != NULL)
490214 {
490215 memcpy (address, par, (size_t) 6);
490216 }
490217 //
490218 // ---------------------------------------------------
490219 // INITIALIZATION SEQUENCE
490220 // ---------------------------------------------------
490221 //
490222 // Command register (CR)
490223 // .-------------------------------.
490224 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
490225 // |-------------------------------|
490226 // | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0x21
490227 // `-------------------------------'
490228 // \_____/ \_________/ |
490229 // | | STOP
490230 // | |
490231 // | Abort/complete
490232 // | remote DMA
490233 // |
490234 // Register
490235 // page 0
490236 //
490237 out_8 ((io + NE2K_CR), 0x21);
490238 //
490239 // There is no need to check the ISR value. At this
490240 // point,
490241 // ISR might report a reset status or a remote DMA
490242 // complete.
490243 // Go to the DCR register.
490244 //
490245 // Data configuration register (DCR)
490246 // .-------------------------------.
490247 // | - |FT1|FT0|ARM| LS|LAS|BOS|WTS|
490248 // |-------------------------------|
490249 // | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0x48
490250 // `-------------------------------'
490251 // \_____/ : | : : :
490252 // | : | : : Byte DMA transfer
490253 // | : | : :
490254 // | : | : Little endian byte order
490255 // | : | :
490256 // | : | Dual 16 bit DMA mode
490257 // | : |
490258 // | : Loopback OFF (normal operation)
490259 // | :
490260 // | Send Command non executed: all frames removed
490261 // from
490262 // | Buffer Ring under program control
490263 // |
490264 // FIFO threshold 8 bytes
490265 //
490266 out_8 ((io + NE2K_DCR), 0x48);
490267 //
490268 // Reset remote byte count registers.
490269 //
490270 out_8 ((io + NE2K_RBCR0), 0x00);
490271 out_8 ((io + NE2K_RBCR1), 0x00);
490272 //
490273 // Receive configuration register (RCR)
490274 // .-------------------------------.
490275 // | - | - |MON|PRO| AM| AB| AR|SEP|
490276 // |-------------------------------|
490277 // | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0x04
490278 // `-------------------------------'
490279 // : : : | : :
490280 // : : : | : Frames with receive errors are
490281 // : : : | : rejected
490282 // : : : | :
490283 // : : : | Frames with fewer than 64 bytes rejected
490284 // : : : |
490285 // : : : Frames with broadcast destination address
490286 // : : : accepted
490287 // : : :
490288 // : : Frames with multicast destination address
490289 // : : not checked
490290 // : :
490291 // : Physical address of node must match the station
490292 // : address
490293 // :
490294 // Frames buffered to memory
490295 //
490296 // Normal operation and broadcast accepted.
490297 //
490298 out_8 ((io + NE2K_RCR), 0x04);
490299 //
490300 // Transmit page start (local DMA).
490301 //
490302 out_8 ((io + NE2K_TPSR), NE2K_TX_START);
490303 //
490304 // Transmit configuration register (TCR)
490305 // .--------------------------------.
490306 // | - | - | - |OFST|ATD|LB1|LB0|CRC|
490307 // |--------------------------------|
490308 // | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0x02
490309 // `--------------------------------'
490310 // \_____/ :
490311 // | CRC appended by the transmitter
490312 // |
490313 // Internal loopback (mode 1)
490314 //
490315 // [Loopback is not supported by Bochs]
490316 //
490317 // Transmit loopback.
490318 //
490319 out_8 ((io + NE2K_TCR), 0x02);
490320 //
490321 // Set receive buffer page start (local DMA).
490322 //
490323 out_8 ((io + NE2K_PSTART), NE2K_RX_START);
490324 //
490325 // Set boundary: the frame not yet read. At the
490326 // moment, it is the same
490327 // as the receive buffer page start.
490328 //
490329 out_8 ((io + NE2K_BNRY), NE2K_RX_START);
490330 //
490331 // Set receive buffer page stop (local DMA).
490332 //
490333 out_8 ((io + NE2K_PSTOP), NE2K_RX_STOP);
490334 //
490335 // Command register (CR)
490336 // .-------------------------------.
490337 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
490338 // |-------------------------------|
490339 // | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0x61
490340 // `-------------------------------'
490341 // \_____/ \_________/ |
490342 // | | STOP
490343 // | |
490344 // | Abort/complete
490345 // | remote DMA
490346 // |
490347 // Register
490348 // page 1
490349 //
490350 out_8 ((io + NE2K_CR), 0x61);
490351 //
490352 // Save physical address and multicast address.
490353 //
490354 out_8 ((io + NE2K_PAR0), par[0]);
490355 out_8 ((io + NE2K_PAR1), par[1]);
490356 out_8 ((io + NE2K_PAR2), par[2]);
490357 out_8 ((io + NE2K_PAR3), par[3]);
490358 out_8 ((io + NE2K_PAR4), par[4]);
490359 out_8 ((io + NE2K_PAR5), par[5]);
490360 //
490361 out_8 ((io + NE2K_MAR0), 0);
490362 out_8 ((io + NE2K_MAR1), 0);
490363 out_8 ((io + NE2K_MAR2), 0);
490364 out_8 ((io + NE2K_MAR3), 0);
490365 out_8 ((io + NE2K_MAR4), 0);
490366 out_8 ((io + NE2K_MAR5), 0);
490367 out_8 ((io + NE2K_MAR6), 0);
490368 out_8 ((io + NE2K_MAR7), 0);
490369 //
490370 // Set current page: the first frame to be saved
490371 // inside the receive
490372 // buffer. At the moment, it is the same as the
490373 // buffer page start.
490374 //
490375 out_8 ((io + NE2K_CURR), NE2K_RX_START);
490376 //
490377 // Command register (CR)
490378 // .-------------------------------.
490379 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
490380 // |-------------------------------|
490381 // | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0x22
490382 // `-------------------------------'
490383 // \_____/ \_________/ |
490384 // | | START
490385 // | |
490386 // | Abort/complete
490387 // | remote DMA
490388 // |
490389 // Register
490390 // page 0
490391 //
490392 out_8 ((io + NE2K_CR), 0x22);
490393 //
490394 // Reset all ISR register flags.
490395 //
490396 out_8 ((io + NE2K_ISR), 0xFF);
490397 //
490398 // ISR will be polled, but received packets will
490399 // fire the IRQ,
490400 // although it is not necessary. So the IMR
490401 // (Interrupt mask register)
490402 // is now set properly with the value 0x01.
490403 //
490404 // Interrupt mask register (IMR)
490405 // .---------------------------------------.
490406 // | -- |RDCE|CNTE|OVWE|TXEE|RXEE|PTXE|PRXE|
490407 // |---------------------------------------|
490408 // | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0x01
490409 // `---------------------------------------'
490410 // |
490411 // Enable interrupt when packet
490412 // received
490413 //
490414 out_8 ((io + NE2K_IMR), 0x01);
490415 //
490416 // Transmit configuration register (TCR)
490417 // .--------------------------------.
490418 // | - | - | - |OFST|ATD|LB1|LB0|CRC|
490419 // |--------------------------------|
490420 // | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0x00
490421 // `--------------------------------'
490422 //
490423 // Normal operation.
490424 //
490425 out_8 ((io + NE2K_TCR), 0x00);
490426 //
490427 return (0);
490428 }
|
|
94.4.24
kernel/driver/nic/ne2k/ne2k_rx.c
Si veda la sezione 93.16.
500001 #include <kernel/driver/pci.h>
500002 #include <kernel/net.h>
500003 #include <kernel/driver/nic/ne2k.h>
500004 #include <kernel/ibm_i386.h>
500005 #include <errno.h>
500006 #include <kernel/lib_k.h>
500007 #include <kernel/lib_s.h>
500008 //----------------------------------------------------------
500009 #define DEBUG 0
500010 //----------------------------------------------------------
500011 int
500012 ne2k_rx (uintptr_t io)
500013 {
500014 int i;
500015 int bytes;
500016 int curr;
500017 int bnry;
500018 int next;
500019 int frame_status;
500020 int frame_size;
500021 int status;
500022 int n = net_index_eth (0, NULL, io);
500023 net_buffer_eth_t *buffer;
500024 //
500025 // Verify to have found a valid Ethernet device.
500026 //
500027 if (n < 0)
500028 {
500029 errset (ENODEV);
500030 return (-1);
500031 }
500032 //
500033 // Command register (CR)
500034 // .-------------------------------.
500035 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
500036 // |-------------------------------|
500037 // | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0x62
500038 // `-------------------------------'
500039 // \_____/ \_________/ |
500040 // | | START
500041 // | |
500042 // | Abort/complete remote DMA
500043 // |
500044 // Register page 1
500045 //
500046 out_8 ((io + NE2K_CR), 0x62);
500047 //
500048 // Get the current position.
500049 //
500050 curr = in_8 (io + NE2K_CURR);
500051 //
500052 // Command register (CR)
500053 // .-------------------------------.
500054 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
500055 // |-------------------------------|
500056 // | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0x22
500057 // `-------------------------------'
500058 // \_____/ \_________/ |
500059 // | | START
500060 // | |
500061 // | Abort/complete remote DMA
500062 // |
500063 // Register page 0
500064 //
500065 out_8 ((io + NE2K_CR), 0x22);
500066 //
500067 // Get the boundary.
500068 //
500069 bnry = in_8 (io + NE2K_BNRY);
500070 //
500071 // ---------------------------------------------------
500072 // The function is run because at least a frame was
500073 // received:
500074 // if index `bnry' and index `curr' are the same,
500075 // all the receive
500076 // ring buffer is to be copied.
500077 // ---------------------------------------------------
500078 //
500079 // Get all the frames ready from the internal
500080 // buffer.
500081 //
500082 while (1)
500083 {
500084 //
500085 // Find a place inside the frame table.
500086 //
500087 buffer = net_buffer_eth (n);
500088 //
500089 // Check to have a valid buffer pointer.
500090 //
500091 if (buffer == NULL)
500092 {
500093 errset (errno);
500094 return (-1);
500095 }
500096 //
500097 // First read 4 bytes starting from `bnry'.
500098 //
500099 out_8 ((io + NE2K_RBCR0), 4);
500100 out_8 ((io + NE2K_RBCR1), 0);
500101 //
500102 // Set the remote DMA address to bnry.
500103 //
500104 out_8 ((io + NE2K_RSAR0), 0x00); // Must be
500105 // zero.
500106 out_8 ((io + NE2K_RSAR1), bnry);
500107 //
500108 // Command register (CR)
500109 // .-------------------------------.
500110 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
500111 // |-------------------------------|
500112 // | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0x0A
500113 // `-------------------------------'
500114 // \_____/ \_________/ |
500115 // | | START
500116 // | |
500117 // | Read
500118 // |
500119 // Register page 0
500120 //
500121 out_8 (io + NE2K_CR, 0x0A);
500122 //
500123 // Frame status
500124 //
500125 frame_status = in_8 (io + NE2K_DATA);
500126 //
500127 // Next frame.
500128 //
500129 next = in_8 (io + NE2K_DATA);
500130 //
500131 // Frame size low.
500132 //
500133 frame_size = in_8 (io + NE2K_DATA);
500134 //
500135 // Frame size high
500136 //
500137 frame_size += (in_8 (io + NE2K_DATA) * 256);
500138 //
500139 // Interrupt status register (ISR)
500140 // .-------------------------------.
500141 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
500142 // |-------------------------------|
500143 // | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0x40
500144 // `-------------------------------'
500145 // |
500146 // Remote DMA complete
500147 //
500148 // Verify to have finished with DMA transfer.
500149 //
500150 status = ne2k_isr_expect (io, 0x40);
500151 if (status)
500152 {
500153 errset (errno);
500154 return (-1);
500155 }
500156 //
500157 // Now read again all the frame plus header (the
500158 // initial 4 bytes).
500159 //
500160 buffer->clock = k_clock ();
500161 buffer->size = frame_size - 4;
500162 //
500163 if (DEBUG)
500164 {
500165 k_printf
500166 ("0x%02x[BNRY=0x%02x "
500167 "CURR=0x%02x]0x%02x size=%i\n",
500168 NE2K_RX_START, bnry, curr, NE2K_RX_STOP,
500169 frame_size);
500170 }
500171 //
500172 if (next == bnry)
500173 {
500174 k_printf
500175 ("[%s] next==bnry but should "
500176 "not happen!\n", __func__);
500177 errset (E_DRIVER_FAULT);
500178 return (-1);
500179 }
500180 //
500181 if (next > bnry)
500182 {
500183 bytes = frame_size;
500184 }
500185 //
500186 if (next < bnry)
500187 {
500188 //
500189 // Read up to the bottom.
500190 //
500191 bytes = ((NE2K_RX_STOP - bnry) * 256);
500192 bytes = min (bytes, frame_size);
500193 }
500194 //
500195 // Read frame content: first part.
500196 //
500197 out_8 ((io + NE2K_RBCR0), bytes & 0xFF);
500198 out_8 ((io + NE2K_RBCR1), bytes >> 8);
500199 //
500200 out_8 ((io + NE2K_RSAR0), 0); // MUST be
500201 // zero. :-(
500202 out_8 ((io + NE2K_RSAR1), bnry);
500203 //
500204 // Command register (CR)
500205 // .-------------------------------.
500206 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
500207 // |-------------------------------|
500208 // | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0x0A
500209 // `-------------------------------'
500210 // \_____/ \_________/ |
500211 // | | START
500212 // | |
500213 // | Read
500214 // |
500215 // Register page 0
500216 //
500217 out_8 (io + NE2K_CR, 0x0A);
500218 //
500219 // Jump the first four bytes (no way to start
500220 // after
500221 // the page start).
500222 //
500223 in_8 (io + NE2K_DATA);
500224 in_8 (io + NE2K_DATA);
500225 in_8 (io + NE2K_DATA);
500226 in_8 (io + NE2K_DATA);
500227 bytes -= 4;
500228 //
500229 // Get the frame data.
500230 //
500231 i = 0;
500232 for (; bytes > 0; i++, bytes--)
500233 {
500234 buffer->frame.octet[i] = in_8 (io + NE2K_DATA);
500235 }
500236 //
500237 // Interrupt status register (ISR)
500238 // .-------------------------------.
500239 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
500240 // |-------------------------------|
500241 // | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0x40
500242 // `-------------------------------'
500243 // |
500244 // Remote DMA complete
500245 //
500246 // Verify to have finished with DMA transfer.
500247 //
500248 status = ne2k_isr_expect (io, 0x40);
500249 if (status)
500250 {
500251 errset (errno);
500252 return (-1);
500253 }
500254 //
500255 if (next < bnry)
500256 {
500257 //
500258 // There might be a second part to read.
500259 //
500260 bytes =
500261 frame_size - ((NE2K_RX_STOP - bnry) * 256);
500262 }
500263 //
500264 if (bytes > 0)
500265 {
500266 //
500267 out_8 ((io + NE2K_RBCR0), bytes & 0xFF);
500268 out_8 ((io + NE2K_RBCR1), bytes >> 8);
500269 //
500270 out_8 ((io + NE2K_RSAR0), 0);
500271 out_8 ((io + NE2K_RSAR1), NE2K_RX_START);
500272 //
500273 // Command register (CR)
500274 // .-------------------------------.
500275 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
500276 // |-------------------------------|
500277 // | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0x0A
500278 // `-------------------------------'
500279 // \_____/ \_________/ |
500280 // | | START
500281 // | |
500282 // | Read
500283 // |
500284 // Register page 0
500285 //
500286 out_8 (io + NE2K_CR, 0x0A);
500287 //
500288 for (; bytes > 0; i++, bytes--)
500289 {
500290 buffer->frame.octet[i] =
500291 in_8 (io + NE2K_DATA);
500292 }
500293 //
500294 // Interrupt status register (ISR)
500295 // .-------------------------------.
500296 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
500297 // |-------------------------------|
500298 // | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0x40
500299 // `-------------------------------'
500300 // |
500301 // Remote DMA complete
500302 //
500303 // Verify to have finished with DMA
500304 // transfer.
500305 //
500306 status = ne2k_isr_expect (io, 0x40);
500307 if (status)
500308 {
500309 errset (errno);
500310 return (-1);
500311 }
500312 }
500313 //
500314 // Update BNRY.
500315 //
500316 bnry = next;
500317 out_8 (io + NE2K_BNRY, bnry);
500318 //
500319 // If the new bnry is equal to curr, the loop is
500320 // finished.
500321 //
500322 if (bnry == curr)
500323 {
500324 //
500325 // finish.
500326 //
500327 return (0);
500328 }
500329 }
500330 }
|
|
94.4.25
kernel/driver/nic/ne2k/ne2k_rx_reset.c
Si veda la sezione 93.16.
510001 #include <kernel/driver/pci.h>
510002 #include <kernel/driver/nic/ne2k.h>
510003 #include <kernel/ibm_i386.h>
510004 #include <errno.h>
510005 #include <kernel/lib_k.h>
510006 #include <kernel/lib_s.h>
510007 //----------------------------------------------------------
510008 #define DEBUG 1
510009 //----------------------------------------------------------
510010 int
510011 ne2k_rx_reset (uintptr_t io)
510012 {
510013 int status;
510014 //
510015 // Command register (CR)
510016 // .-------------------------------.
510017 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
510018 // |-------------------------------|
510019 // | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0x21
510020 // `-------------------------------'
510021 // \_____/ \_________/ |
510022 // | | STOP
510023 // | |
510024 // | Abort/complete remote DMA
510025 // |
510026 // Register page 0
510027 //
510028 out_8 ((io + NE2K_CR), 0x21);
510029 //
510030 // Interrupt status register (ISR)
510031 // .-------------------------------.
510032 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
510033 // |-------------------------------|
510034 // | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0x80
510035 // `-------------------------------'
510036 // |
510037 // Reset
510038 //
510039 status = ne2k_isr_expect (io, 0x80);
510040 if (status)
510041 {
510042 errset (errno);
510043 return (-1);
510044 }
510045 //
510046 //
510047 //
510048 out_8 ((io + NE2K_RBCR0), 0);
510049 out_8 ((io + NE2K_RBCR1), 0);
510050 //
510051 // Command register (CR)
510052 // .-------------------------------.
510053 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
510054 // |-------------------------------|
510055 // | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0x22
510056 // `-------------------------------'
510057 // \_____/ \_________/ |
510058 // | | START
510059 // | |
510060 // | Abort/complete remote DMA
510061 // |
510062 // Register page 0
510063 //
510064 out_8 (io + NE2K_CR, 0x22);
510065 //
510066 return (0);
510067 }
|
|
94.4.26
kernel/driver/nic/ne2k/ne2k_tx.c
Si veda la sezione 93.16.
520001 #include <kernel/driver/pci.h>
520002 #include <kernel/driver/nic/ne2k.h>
520003 #include <kernel/ibm_i386.h>
520004 #include <errno.h>
520005 #include <kernel/lib_k.h>
520006 #include <kernel/lib_s.h>
520007 //----------------------------------------------------------
520008 int
520009 ne2k_tx (uintptr_t io, void *buffer, size_t size)
520010 {
520011 int i;
520012 int status;
520013 uint8_t *b = buffer;
520014 //
520015 // Read the command register to see if the NIC is
520016 // transmitting.
520017 // The value 0x26 tells that the NIC is
520018 // transmitting.
520019 //
520020 // Command register (CR)
520021 // .-------------------------------.
520022 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
520023 // |-------------------------------|
520024 // | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0x26
520025 // `-------------------------------'
520026 // \_____/ \_________/ | |
520027 // | | | Start
520028 // | | Transmit frame
520029 // | Abort/complete
520030 // | remote DMA
520031 // Register
520032 // page 0
520033 //
520034 status = in_8 (io + NE2K_CR);
520035 if (status == 0x26)
520036 {
520037 errset (EBUSY);
520038 return (-1);
520039 }
520040 //
520041 // Set up the frame size: the size is split into
520042 // RBCR0 and RBCR1
520043 // registers.
520044 //
520045 out_8 ((io + NE2K_RBCR0), (size & 0xFF));
520046 out_8 ((io + NE2K_RBCR1), (size >> 8));
520047 //
520048 // Set the remote DMA address.
520049 //
520050 out_8 ((io + NE2K_RSAR0), 0x00); // Must be
520051 // zero.
520052 out_8 ((io + NE2K_RSAR1), NE2K_TX_BUFFER);
520053 //
520054 // Command register (CR)
520055 // .-------------------------------.
520056 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
520057 // |-------------------------------|
520058 // | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0x12
520059 // `-------------------------------'
520060 // \_____/ \_________/ |
520061 // | | Start
520062 // | |
520063 // | Write
520064 // Register
520065 // page 0
520066 //
520067 out_8 ((io + NE2K_CR), 0x12);
520068 //
520069 // Write to the data port all the frame.
520070 //
520071 for (i = 0; i < size; i++)
520072 {
520073 out_8 ((io + NE2K_DATA), b[i]);
520074 }
520075 //
520076 // Interrupt status register (ISR)
520077 // .-------------------------------.
520078 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
520079 // |-------------------------------|
520080 // | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0x40
520081 // `-------------------------------'
520082 // |
520083 // Remote DMA complete
520084 //
520085 // Verify to have finished with DMA transfer.
520086 //
520087 status = ne2k_isr_expect (io, 0x40);
520088 if (status)
520089 {
520090 errset (errno);
520091 return (-1);
520092 }
520093 //
520094 // Set transmit page start, to the transmit buffer.
520095 //
520096 out_8 (io + NE2K_TPSR, NE2K_TX_BUFFER);
520097 //
520098 // Set transmit byte count (frame size).
520099 //
520100 out_8 ((io + NE2K_TBCR0), (size & 0xFF));
520101 out_8 ((io + NE2K_TBCR1), (size >> 8));
520102 //
520103 // Command register (CR)
520104 // .-------------------------------.
520105 // |PS1|PS0|RD2|RD1|RD0|TXP|STA|STP|
520106 // |-------------------------------|
520107 // | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0x26
520108 // `-------------------------------'
520109 // \_____/ \_________/ | |
520110 // | | | Start
520111 // | | Transmit frame
520112 // | Abort/complete remote DMA
520113 // Register
520114 // page 0
520115 //
520116 // Send frame!
520117 //
520118 out_8 ((io + NE2K_CR), 0x26);
520119 //
520120 // Interrupt status register (ISR)
520121 // .-------------------------------.
520122 // |RST|RDC|CNT|OVW|TXE|RXE|PTX|PRX|
520123 // |-------------------------------|
520124 // | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0x0A
520125 // `-------------------------------'
520126 // | |
520127 // | Frame transmitted with no errors
520128 // Transmit error
520129 //
520130 // Wait the end of transmission: might get a good
520131 // transmission
520132 // report, or an error transmission report.
520133 //
520134 status = ne2k_isr_expect (io, 0x0A);
520135 if (status)
520136 {
520137 errset (errno);
520138 return (-1);
520139 }
520140 //
520141 // Transmit status (TSR)
520142 // .-------------------------------.
520143 // |OWC|CDH| FU|CRS|ABT|COL| - |PTX|
520144 // |-------------------------------|
520145 // | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0x38
520146 // `-------------------------------'
520147 // | | |
520148 // | | Transmit aborted
520149 // | Carrier sense lost
520150 // FIFO underrun
520151 //
520152 // Check if there was an error, during transmission.
520153 //
520154 status = in_8 (io + NE2K_TSR);
520155 if (status & 0x38)
520156 {
520157 errset (EIO);
520158 return (-1);
520159 }
520160 //
520161 // Done.
520162 //
520163 return (0);
520164 //
520165 }
|
|
94.4.27
kernel/driver/pci.h
Si veda la sezione 93.19.
530001 #ifndef _KERNEL_DRIVER_PCI_H
530002 #define _KERNEL_DRIVER_PCI_H 1
530003 //----------------------------------------------------------
530004 #include <stdint.h>
530005 #include <sys/types.h>
530006 //----------------------------------------------------------
530007 //
530008 #define PCI_MAX_DEVICES 8
530009 #define PCI_MAX_BUSES 256 // Fixed.
530010 #define PCI_MAX_SLOTS 32 // Fixed.
530011 //
530012 #define PCI_CONFIG_ADDRESS 0x0CF8
530013 #define PCI_CONFIG_DATA 0x0CFC
530014 //
530015 // CONFIG_ADDRESS register structure.
530016 //
530017 typedef union
530018 {
530019 uint32_t selector;
530020 struct
530021 {
530022 uint32_t zero:2,
530023 reg:6,
530024 function:3, slot:5, bus:8, reserved:7, enable:1;
530025 };
530026 } pci_address_t;
530027 //
530028 // CONFIG_DATA register structures.
530029 //
530030 typedef union
530031 {
530032 uint32_t r[16];
530033 struct
530034 {
530035 struct
530036 {
530037 uint32_t vendor_id:16, device_id:16;
530038 //
530039 uint32_t command:16, status:16;
530040 //
530041 uint32_t revision_id:8,
530042 prog_if:8, subclass:8, class_code:8;
530043 //
530044 uint32_t cache_line_size:8,
530045 latency_timer:8,
530046 header_type:7, multi_function:1, bist:8;
530047 //
530048 uint32_t bar0;
530049 uint32_t bar1;
530050 uint32_t bar2;
530051 uint32_t bar3;
530052 uint32_t bar4;
530053 uint32_t bar5;
530054 uint32_t cardbus_cis_pointer;
530055 uint32_t expansion_rom_base_address;
530056 //
530057 uint32_t subsystem_vendor_id:16, subsystem_id:16;
530058 //
530059 uint32_t capabilities_pointer:8, reserved_1:24;
530060 //
530061 uint32_t reserved_2;
530062 //
530063 uint32_t interrupt_line:8,
530064 interrupt_pin:8, min_grant:8, max_latency:8;
530065 };
530066 };
530067 } pci_header_type_00_t;
530068 //
530069 //----------------------------------------------------------
530070 //
530071 // PCI table row.
530072 //
530073 typedef struct
530074 {
530075 unsigned char bus;
530076 unsigned char slot;
530077 unsigned short int vendor_id;
530078 unsigned short int device_id;
530079 unsigned char class_code;
530080 unsigned char subclass;
530081 unsigned char prog_if;
530082 uintptr_t base_io;
530083 unsigned char irq;
530084 } pci_t;
530085 //
530086 extern pci_t pci_table[PCI_MAX_DEVICES];
530087 //
530088 //----------------------------------------------------------
530089 void pci_init (void);
530090 //----------------------------------------------------------
530091 #endif
|
|
94.4.28
kernel/driver/pci/pci_init.c
Si veda la sezione 93.19.
540001 #include <kernel/driver/pci.h>
540002 #include <kernel/ibm_i386.h>
540003 #include <errno.h>
540004 //----------------------------------------------------------
540005 extern pci_t pci_table[PCI_MAX_DEVICES];
540006 //----------------------------------------------------------
540007 void
540008 pci_init (void)
540009 {
540010 pci_header_type_00_t pci;
540011 pci_address_t pci_addr;
540012 //
540013 int t; // PCI table index.
540014 int b; // PCI bus index.
540015 int s; // PCI slot index.
540016 int r; // PCI header register index.
540017 //
540018 // Reset the PCI table.
540019 //
540020 for (t = 0; t < PCI_MAX_DEVICES; t++)
540021 {
540022 pci_table[t].bus = 0;
540023 pci_table[t].slot = 0;
540024 pci_table[t].vendor_id = 0;
540025 pci_table[t].device_id = 0;
540026 pci_table[t].class_code = 0;
540027 pci_table[t].subclass = 0;
540028 pci_table[t].prog_if = 0;
540029 pci_table[t].base_io = 0;
540030 pci_table[t].irq = 0;
540031 }
540032 //
540033 // Scan PCI buses and slots.
540034 //
540035 t = 0;
540036 //
540037 for (b = 0; b < PCI_MAX_BUSES && t < PCI_MAX_DEVICES; b++)
540038 {
540039 //
540040 // Will not check multi functions devices (we
540041 // are shure that
540042 // we don't have them).
540043 //
540044 for (s = 0;
540045 s < PCI_MAX_SLOTS && t < PCI_MAX_DEVICES; s++)
540046 {
540047 pci_addr.selector = 0;
540048 pci_addr.enable = 1;
540049 pci_addr.bus = b;
540050 pci_addr.slot = s;
540051 //
540052 pci_addr.reg = 0;
540053 out_32 (PCI_CONFIG_ADDRESS, pci_addr.selector);
540054 pci.r[0] = in_32 (PCI_CONFIG_DATA);
540055 //
540056 if (pci.r[0] == 0xFFFFFFFF)
540057 {
540058 //
540059 // There is no such bus:slot
540060 // combination!
540061 //
540062 continue;
540063 }
540064 else
540065 {
540066 for (r = 1; r < 16; r++)
540067 {
540068 pci_addr.reg = r;
540069 out_32 (PCI_CONFIG_ADDRESS,
540070 pci_addr.selector);
540071 pci.r[r] = in_32 (PCI_CONFIG_DATA);
540072 }
540073 }
540074 //
540075 // We consider only PCI header type 0x00!
540076 //
540077 if (pci.header_type != 0)
540078 {
540079 continue;
540080 }
540081 //
540082 // We do not consider PCI bridge devices!
540083 //
540084 if (pci.class_code == 0x06)
540085 {
540086 continue;
540087 }
540088 //
540089 // Save the device inside the PCI table.
540090 //
540091 pci_table[t].bus = b;
540092 pci_table[t].slot = s;
540093 pci_table[t].vendor_id = pci.vendor_id;
540094 pci_table[t].device_id = pci.device_id;
540095 pci_table[t].class_code = pci.class_code;
540096 pci_table[t].subclass = pci.subclass;
540097 pci_table[t].prog_if = pci.prog_if;
540098 pci_table[t].base_io = pci.bar0 & 0xFFFFFFFC;
540099 pci_table[t].irq = pci.interrupt_line;
540100 //
540101 k_printf ("[%s]: %04x:%04x io=%04x irq=%i\n",
540102 __func__, pci_table[t].vendor_id,
540103 pci_table[t].device_id,
540104 pci_table[t].base_io, pci_table[t].irq);
540105 //
540106 // Next PCI table row.
540107 //
540108 t++;
540109 }
540110 }
540111 }
|
|
94.4.29
kernel/driver/pci/pci_public.c
Si veda la sezione 93.19.
550001 #include <kernel/driver/pci.h>
550002 //----------------------------------------------------------
550003 pci_t pci_table[PCI_MAX_DEVICES];
550004 //----------------------------------------------------------
|
|
94.4.30
kernel/driver/screen.h
Si veda la sezione 93.22.
560001 #ifndef _KERNEL_DRIVER_SCREEN_H
560002 #define _KERNEL_DRIVER_SCREEN_H 1
560003 //----------------------------------------------------------
560004 #include <restrict.h>
560005 #include <stdint.h>
560006 //----------------------------------------------------------
560007 // Virtual consoles data and VGA references.
560008 //
560009 #define SCREEN_MAX 4
560010 #define SCREEN_ROWS 25
560011 #define SCREEN_COLS 80
560012 #define SCREEN_CELLS (SCREEN_ROWS * SCREEN_COLS)
560013 //
560014 #define VGA_ATTR 0x07
560015 #define VGA_ADDR 0xB8000
560016 #define VGA_CELL ((uint16_t *) VGA_ADDR)
560017 //
560018 typedef struct
560019 {
560020 uint16_t cell[SCREEN_CELLS]; // [1]
560021 int position;
560022 } screen_t;
560023 //
560024 // [1] Every character on the screen needs another
560025 // attribute byte.
560026 //
560027 //----------------------------------------------------------
560028 extern int screen_active;
560029 extern screen_t screen_table[];
560030 //----------------------------------------------------------
560031 int screen_clear (screen_t * screen);
560032 screen_t *screen_current (void);
560033 void screen_init (void);
560034 int screen_new_line (screen_t * screen);
560035 int screen_number (screen_t * screen);
560036 screen_t *screen_pointer (int scrn);
560037 int screen_putc (screen_t * screen, int c);
560038 int screen_scroll (screen_t * screen);
560039 int screen_select (screen_t * screen);
560040 void screen_update (screen_t * screen);
560041 //----------------------------------------------------------
560042 #define screen_cell(c, attrib) \
560043 ((uint16_t) c \
560044 | ((((uint16_t) attrib) << 8) & 0xFF00))
560045 //----------------------------------------------------------
560046 #endif
|
|
94.4.31
kernel/driver/screen/screen_clear.c
Si veda la sezione 93.22.
570001 #include <kernel/driver/screen.h>
570002 #include <errno.h>
570003 //----------------------------------------------------------
570004 int
570005 screen_clear (screen_t * screen)
570006 {
570007 int j;
570008 //
570009 // Check argument.
570010 //
570011 if (screen == NULL)
570012 {
570013 errset (EINVAL);
570014 return (-1);
570015 }
570016 //
570017 // Clear the virtual screen.
570018 //
570019 for (j = 0; j < SCREEN_CELLS; j++)
570020 {
570021 screen->cell[j] = screen_cell (' ', VGA_ATTR);
570022 }
570023 //
570024 // Place the cursor at the top.
570025 //
570026 screen->position = 0;
570027 //
570028 // Update the screen if it is the active one.
570029 //
570030 screen_update (screen);
570031 //
570032 // Ok.
570033 //
570034 return (0);
570035 }
|
|
94.4.32
kernel/driver/screen/screen_current.c
Si veda la sezione 93.22.
580001 #include <kernel/driver/screen.h>
580002 //----------------------------------------------------------
580003 screen_t *
580004 screen_current (void)
580005 {
580006 if (screen_active >= 0 && screen_active < SCREEN_MAX)
580007 {
580008 return &screen_table[screen_active];
580009 }
580010 else
580011 {
580012 return &screen_table[0];
580013 }
580014 }
|
|
94.4.33
kernel/driver/screen/screen_init.c
Si veda la sezione 93.22.
590001 #include <kernel/driver/screen.h>
590002 //----------------------------------------------------------
590003 void
590004 screen_init (void)
590005 {
590006 int i;
590007 int j;
590008 //
590009 // Reset and clear all virtual consoles.
590010 //
590011 for (i = 0; i < SCREEN_MAX; i++)
590012 {
590013 //
590014 // Reset position.
590015 //
590016 screen_table[i].position = 0;
590017 //
590018 for (j = 0; j < SCREEN_CELLS; j++)
590019 {
590020 screen_table[i].cell[j] =
590021 screen_cell (' ', VGA_ATTR);
590022 }
590023 }
590024 //
590025 // Select the first screen.
590026 //
590027 screen_active = 0;
590028 }
|
|
94.4.34
kernel/driver/screen/screen_new_line.c
Si veda la sezione 93.22.
600001 #include <kernel/driver/screen.h>
600002 #include <errno.h>
600003 //----------------------------------------------------------
600004 int
600005 screen_new_line (screen_t * screen)
600006 {
600007 int row;
600008 //
600009 // Check argument.
600010 //
600011 if (screen == NULL)
600012 {
600013 errset (EINVAL);
600014 return (-1);
600015 }
600016 //
600017 // Find row position on screen.
600018 //
600019 row = (screen->position / SCREEN_COLS);
600020 //
600021 // We want to go one row down.
600022 //
600023 row++;
600024 //
600025 // Scroll the screen if necessary.
600026 //
600027 for (; row >= SCREEN_ROWS; row--)
600028 {
600029 screen_scroll (screen);
600030 }
600031 //
600032 // Reset position at the beginning of the line.
600033 //
600034 screen->position = row * SCREEN_COLS;
600035 //
600036 // Update the video if it is the current one. This
600037 // is necessary to
600038 // update the cursor position, if the original
600039 // column was not zero.
600040 //
600041 screen_update (screen);
600042 //
600043 // Ok.
600044 //
600045 return (0);
600046 }
|
|
94.4.35
kernel/driver/screen/screen_number.c
Si veda la sezione 93.22.
610001 #include <kernel/driver/screen.h>
610002 #include <stddef.h>
610003 #include <errno.h>
610004 #include <kernel/lib_k.h>
610005 //----------------------------------------------------------
610006 int
610007 screen_number (screen_t * screen)
610008 {
610009 ptrdiff_t distance;
610010 int n;
610011 //
610012 if (screen == NULL)
610013 {
610014 errset (EINVAL);
610015 return (-1);
610016 }
610017 //
610018 distance = (void *) screen - (void *) &screen_table[0];
610019 //
610020 n = (distance % (sizeof (screen_t)));
610021 //
610022 if (n != 0)
610023 {
610024 errset (EINVAL); // Invalid pointer placement.
610025 return (-1);
610026 }
610027 //
610028 n = (distance / (sizeof (screen_t)));
610029 //
610030 if (n < 0 || n > SCREEN_MAX)
610031 {
610032 errset (EINVAL); // Pointer outside the screen
610033 // table.
610034 return (-1);
610035 }
610036 //
610037 // If we are here, variable `n' holds the right
610038 // screen number.
610039 //
610040 return (n);
610041 }
|
|
94.4.36
kernel/driver/screen/screen_pointer.c
Si veda la sezione 93.22.
620001 #include <kernel/driver/screen.h>
620002 #include <errno.h>
620003 //----------------------------------------------------------
620004 screen_t *
620005 screen_pointer (int scrn)
620006 {
620007 if (scrn >= 0 && scrn < SCREEN_MAX)
620008 {
620009 return &screen_table[scrn];
620010 }
620011 else
620012 {
620013 errset (EINVAL);
620014 return (NULL);
620015 }
620016 }
|
|
94.4.37
kernel/driver/screen/screen_public.c
Si veda la sezione 93.22.
630001 #include <kernel/driver/screen.h>
630002 #include <errno.h>
630003 //----------------------------------------------------------
630004 int screen_active;
630005 screen_t screen_table[SCREEN_MAX];
|
|
94.4.38
kernel/driver/screen/screen_putc.c
Si veda la sezione 93.22.
640001 #include <kernel/driver/screen.h>
640002 #include <errno.h>
640003 //----------------------------------------------------------
640004 int
640005 screen_putc (screen_t * screen, int c)
640006 {
640007 int row;
640008 int col;
640009 //
640010 if (screen == NULL)
640011 {
640012 errset (EINVAL);
640013 return (-1);
640014 }
640015 //
640016 // Find row-col position on screen.
640017 //
640018 row = (screen->position / SCREEN_COLS);
640019 col = (screen->position - (row * SCREEN_COLS));
640020 //
640021 //
640022 //
640023 if (c == '\n' || c == '\r')
640024 {
640025 screen_new_line (screen);
640026 return (0);
640027 }
640028 else if (c == '\b')
640029 {
640030 screen->position--;
640031 if (screen->position < 0)
640032 {
640033 screen->position = 0;
640034 }
640035 screen_update (screen);
640036 return (0);
640037 }
640038 else if (screen->position == (SCREEN_CELLS - 1))
640039 {
640040 //
640041 // It is not a control character and we are
640042 // already at the
640043 // last cell of the last row.
640044 //
640045 screen_scroll (screen);
640046 }
640047 //
640048 // If we are here, it is not a control character.
640049 // So: print it.
640050 //
640051 screen->cell[screen->position] =
640052 screen_cell (c, VGA_ATTR);
640053 screen->position++;
640054 screen_update (screen);
640055 //
640056 return (0);
640057 }
|
|
94.4.39
kernel/driver/screen/screen_scroll.c
Si veda la sezione 93.22.
650001 #include <kernel/driver/screen.h>
650002 #include <errno.h>
650003 //----------------------------------------------------------
650004 int
650005 screen_scroll (screen_t * screen)
650006 {
650007 int a; // screen[].cell[] index.
650008 int b; // screen[].cell[] index
650009 //
650010 // Check argument.
650011 //
650012 if (screen == NULL)
650013 {
650014 errset (EINVAL);
650015 return (-1);
650016 }
650017 //
650018 // Move up a line.
650019 //
650020 for (a = 0, b = SCREEN_COLS; b < SCREEN_CELLS; a++, b++)
650021 {
650022 screen->cell[a] = screen->cell[b];
650023 }
650024 //
650025 // Clear last screen line.
650026 //
650027 for (b = (SCREEN_CELLS - SCREEN_COLS);
650028 b < SCREEN_CELLS; b++)
650029 {
650030 screen->cell[b] = screen_cell (' ', VGA_ATTR);
650031 }
650032 //
650033 // Update position.
650034 //
650035 screen->position -= SCREEN_COLS;
650036 if (screen->position < 0)
650037 {
650038 screen->position = 0;
650039 }
650040 //
650041 // Update the video if it is the current one.
650042 //
650043 screen_update (screen);
650044 //
650045 // Ok.
650046 //
650047 return (0);
650048 }
|
|
94.4.40
kernel/driver/screen/screen_select.c
Si veda la sezione 93.22.
660001 #include <kernel/driver/screen.h>
660002 #include <errno.h>
660003 #include <kernel/ibm_i386.h>
660004 //----------------------------------------------------------
660005 int
660006 screen_select (screen_t * screen)
660007 {
660008 int scrn;
660009 //
660010 if (screen == NULL)
660011 {
660012 errset (EINVAL);
660013 return (-1);
660014 }
660015 //
660016 // Get screen number.
660017 //
660018 scrn = screen_number (screen);
660019 if (scrn < 0)
660020 {
660021 errset (EINVAL); // The screen pointer was
660022 // invalid.
660023 return (-1);
660024 }
660025 //
660026 // Set the current screen, update the screen memory
660027 // and put the cursor.
660028 //
660029 screen_active = scrn;
660030 //
660031 screen_update (screen);
660032 //
660033 // Ok.
660034 //
660035 return (0);
660036 }
|
|
94.4.41
kernel/driver/screen/screen_update.c
Si veda la sezione 93.22.
670001 #include <kernel/driver/screen.h>
670002 #include <kernel/ibm_i386.h>
670003 #include <stddef.h>
670004 //----------------------------------------------------------
670005 void
670006 screen_update (screen_t * screen)
670007 {
670008 screen_t *screen_showing;
670009 int j;
670010 unsigned char position_high;
670011 unsigned char position_low;
670012 //
670013 // Check input: if it is the NULL pointer, or it is
670014 // not a valid
670015 // pointer, then select the current screen.
670016 //
670017 if ((screen == NULL) || (screen_number (screen) < 0))
670018 {
670019 screen = screen_current ();
670020 }
670021 //
670022 // Get current screen anyway.
670023 //
670024 screen_showing = screen_current ();
670025 //
670026 // Verify again to be in a valid screen.
670027 //
670028 if (screen_number (screen_showing) < 0)
670029 {
670030 return;
670031 }
670032 //
670033 // If the selected screen is also the current
670034 // screen, then
670035 // must update the content (otherwise there is
670036 // nothing to do).
670037 //
670038 if (screen_showing == screen)
670039 {
670040 //
670041 // Copy virtual screen to real screen memory.
670042 //
670043 for (j = 0; j < SCREEN_CELLS; j++)
670044 {
670045 VGA_CELL[j] = screen->cell[j];
670046 }
670047 //
670048 // Place the cursor.
670049 //
670050 position_high =
670051 (unsigned char) (screen->position >> 8);
670052 position_low = (unsigned char) (screen->position);
670053 //
670054 out_8 (0x3D4, 0x0E);
670055 out_8 (0x3D5, position_high);
670056 out_8 (0x3D4, 0x0F);
670057 out_8 (0x3D5, position_low);
670058 }
670059 }
|
|
94.4.42
kernel/driver/tty.h
Si veda la sezione 93.24.
680001 #ifndef _KERNEL_DRIVER_TTY_H
680002 #define _KERNEL_DRIVER_TTY_H 1
680003 //----------------------------------------------------------
680004 #include <stddef.h>
680005 #include <stdint.h>
680006 #include <stdio.h>
680007 #include <sys/types.h>
680008 #include <kernel/ibm_i386.h>
680009 #include <termios.h>
680010 //----------------------------------------------------------
680011 #define TTYS_CONSOLE 4
680012 #define TTYS_SERIAL 0
680013 #define TTYS_TOTAL (TTYS_CONSOLE + TTYS_SERIAL)
680014 //----------------------------------------------------------
680015 #define TTY_INPUT_LINE_EDITING 0
680016 #define TTY_INPUT_LINE_CLOSED 1
680017 //----------------------------------------------------------
680018 typedef struct
680019 {
680020 dev_t device;
680021 pid_t pgrp; // Process group.
680022 struct termios attr; // termios attributes.
680023 unsigned char status; // 0 = edit, 1 = end edit.
680024 char line[MAX_CANON]; // Canonical input line.
680025 int lpr; // Input line position read.
680026 int lpw; // Input line position write.
680027 } tty_t;
680028 //----------------------------------------------------------
680029 extern tty_t tty_table[TTYS_TOTAL];
680030 //----------------------------------------------------------
680031 tty_t *tty_reference (dev_t device);
680032 dev_t tty_console (dev_t device);
680033 int tty_read (dev_t device);
680034 void tty_write (dev_t device, int c);
680035 void tty_init (void);
680036 //----------------------------------------------------------
680037 #endif
|
|
94.4.43
kernel/driver/tty/tty_console.c
Si veda la sezione 93.24.
690001 #include <sys/os32.h>
690002 #include <kernel/driver/tty.h>
690003 #include <kernel/driver/screen.h>
690004 //----------------------------------------------------------
690005 dev_t
690006 tty_console (dev_t device)
690007 {
690008 static dev_t device_active = DEV_CONSOLE0; // First
690009 // time.
690010 dev_t device_previous;
690011 screen_t *screen;
690012 //
690013 // Check if it required only the current device.
690014 //
690015 if (device == 0)
690016 {
690017 return (device_active);
690018 }
690019 //
690020 // Fix if the device is not valid.
690021 //
690022 if (device > DEV_CONSOLE3 || device < DEV_CONSOLE0)
690023 {
690024 device = DEV_CONSOLE0;
690025 }
690026 //
690027 // Update.
690028 //
690029 device_previous = device_active;
690030 device_active = device;
690031 //
690032 // Get screen pointer.
690033 //
690034 screen = screen_pointer ((int) (device_active & 0x00FF));
690035 //
690036 // Switch.
690037 //
690038 screen_select (screen);
690039 //
690040 // Return previous device value.
690041 //
690042 return (device_previous);
690043 }
|
|
94.4.44
kernel/driver/tty/tty_init.c
Si veda la sezione 93.24.
700001 #include <sys/os32.h>
700002 #include <kernel/driver/tty.h>
700003 #include <kernel/driver/screen.h>
700004 #include <termios.h>
700005 //----------------------------------------------------------
700006 void
700007 tty_init (void)
700008 {
700009 int page; // console page.
700010 //
700011 // Console initialization: console pages correspond
700012 // to the first
700013 // terminal items.
700014 //
700015 for (page = 0; page < TTYS_CONSOLE; page++)
700016 {
700017 tty_table[page].device = DEV_CONSOLE0 + page;
700018 tty_table[page].pgrp = 0;
700019 tty_table[page].line[0] = 0;
700020 tty_table[page].lpr = 0;
700021 tty_table[page].lpw = 0;
700022 tty_table[page].status = TTY_INPUT_LINE_EDITING;
700023 //
700024 // Termios default configuration.
700025 //
700026 tty_table[page].attr.c_iflag = BRKINT | ICRNL;
700027 tty_table[page].attr.c_oflag = 0;
700028 tty_table[page].attr.c_cflag = 0;
700029 tty_table[page].attr.c_lflag =
700030 ECHO | ECHOE | ECHOK | ECHONL | ICANON | ISIG;
700031 //
700032 // VEOF == ASCII EOT
700033 //
700034 tty_table[page].attr.c_cc[VEOF] = 0x04;
700035 //
700036 // VEOL == undefined
700037 //
700038 tty_table[page].attr.c_cc[VEOL] = 0x00;
700039 //
700040 // VERASE == ASCII BS
700041 //
700042 tty_table[page].attr.c_cc[VERASE] = 0x08;
700043 //
700044 // VINTR == ASCII ETX
700045 //
700046 tty_table[page].attr.c_cc[VINTR] = 0x03;
700047 //
700048 // VKILL == undefined
700049 //
700050 tty_table[page].attr.c_cc[VKILL] = 0x00;
700051 //
700052 // VMIN == 0
700053 //
700054 tty_table[page].attr.c_cc[VMIN] = 0x00;
700055 //
700056 // VQUIT == ASCII FS
700057 //
700058 tty_table[page].attr.c_cc[VQUIT] = 0x1C;
700059 //
700060 // VSTART == undefined
700061 //
700062 tty_table[page].attr.c_cc[VSTART] = 0x00;
700063 //
700064 // VSUSP == undefined
700065 //
700066 tty_table[page].attr.c_cc[VSUSP] = 0x00;
700067 //
700068 // VTIME == 0
700069 //
700070 tty_table[page].attr.c_cc[VTIME] = 0x00;
700071 }
700072 //
700073 // Set video mode.
700074 //
700075 screen_init ();
700076 //
700077 // Select the first console.
700078 //
700079 tty_console (DEV_CONSOLE0);
700080 //
700081 // Nothing else to configure (only consoles are
700082 // available).
700083 //
700084 return;
700085 }
|
|
94.4.45
kernel/driver/tty/tty_public.c
Si veda la sezione 93.24.
710001 #include <kernel/driver/tty.h>
710002 //----------------------------------------------------------
710003 tty_t tty_table[TTYS_TOTAL];
|
|
94.4.46
kernel/driver/tty/tty_read.c
Si veda la sezione 93.24.
720001 #include <sys/os32.h>
720002 #include <kernel/driver/tty.h>
720003 #include <kernel/lib_k.h>
720004 //----------------------------------------------------------
720005 int
720006 tty_read (dev_t device)
720007 {
720008 tty_t *tty;
720009 int key;
720010 //
720011 tty = tty_reference (device);
720012 if (tty == NULL)
720013 {
720014 k_printf
720015 ("kernel alert: cannot find terminal device "
720016 "0x%08x!\n", (int) device);
720017 //
720018 return (-1);
720019 }
720020 //
720021 // Read from canonical input line, but only if it is
720022 // time to read.
720023 //
720024 if (tty->status == TTY_INPUT_LINE_CLOSED)
720025 {
720026 if (tty->lpr > tty->lpw)
720027 {
720028 //
720029 // There is nothing to read!
720030 // Reset input line.
720031 //
720032 tty->lpw = 0;
720033 tty->lpr = 0;
720034 tty->status = TTY_INPUT_LINE_EDITING;
720035 //
720036 return (-1);
720037 }
720038 //
720039 // Read the key.
720040 //
720041 key = tty->line[tty->lpr];
720042 //
720043 // Move up the read cursor.
720044 //
720045 tty->lpr++;
720046 }
720047 else
720048 {
720049 return (-1);
720050 }
720051 //
720052 // Return the key.
720053 //
720054 return (key);
720055
720056 }
|
|
94.4.47
kernel/driver/tty/tty_reference.c
Si veda la sezione 93.24.
730001 #include <kernel/driver/tty.h>
730002 //----------------------------------------------------------
730003 tty_t *
730004 tty_reference (dev_t device)
730005 {
730006 int t; // Terminal index.
730007 //
730008 // If device is zero, a reference to the whole table
730009 // is returned.
730010 //
730011 if (device == 0)
730012 {
730013 return (tty_table);
730014 }
730015 //
730016 // Otherwise, a scan is made to find the selected
730017 // device.
730018 //
730019 for (t = 0; t < TTYS_TOTAL; t++)
730020 {
730021 if (tty_table[t].device == device)
730022 {
730023 //
730024 // Device found. Return the pointer.
730025 //
730026 return (&tty_table[t]);
730027 }
730028 }
730029 //
730030 // No device found!
730031 //
730032 return (NULL);
730033 }
|
|
94.4.48
kernel/driver/tty/tty_write.c
Si veda la sezione 93.24.
740001 #include <sys/os32.h>
740002 #include <kernel/driver/tty.h>
740003 #include <kernel/driver/screen.h>
740004 //----------------------------------------------------------
740005 void
740006 tty_write (dev_t device, int c)
740007 {
740008 screen_t *screen;
740009 //
740010 if ((device & 0xFF00) == (DEV_CONSOLE_MAJOR << 8))
740011 {
740012 //
740013 // Get screen pointer.
740014 //
740015 screen = screen_pointer ((int) (device & 0x00FF));
740016 //
740017 screen_putc (screen, c);
740018 }
740019 }
|
|
94.5
os32: «kernel/fs.h»
Si veda la sezione 93.6.
750001 #ifndef _KERNEL_FS_H
750002 #define _KERNEL_FS_H 1
750003 //----------------------------------------------------------
750004 #include <stdint.h>
750005 #include <sys/types.h>
750006 #include <sys/stat.h>
750007 #include <stdio.h>
750008 #include <limits.h>
750009 #include <kernel/memory.h>
750010 #include <sys/socket.h>
750011 #include <netinet/in.h>
750012 #include <netinet/tcp.h>
750013 #include <kernel/net/ip.h>
750014 #include <kernel/net/tcp.h>
750015 #include <sys/os32.h>
750016 //----------------------------------------------------------
750017 #define SB_MAX_INODE_BLOCKS 8 // 8*8192
750018 // inodes max.
750019 #define SB_MAX_ZONE_BLOCKS 8 // 8*8192
750020 // data-zones
750021 // max.
750022 #define SB_BLOCK_SIZE 1024 // Fixed for
750023 // Minix file
750024 // system.
750025 #define SB_MAX_ZONE_SIZE 4096 // log2 max is
750026 // 1.
750027 //----------------------------------------------------------
750028 //
750029 // blocks * (1024 * 8 / 16)
750030 // = number of bits, divided 16.
750031 //
750032 #define SB_MAP_INODE_SIZE (SB_MAX_INODE_BLOCKS*512)
750033 #define SB_MAP_ZONE_SIZE (SB_MAX_ZONE_BLOCKS*512)
750034 //----------------------------------------------------------
750035 //
750036 // Number of zone pointers contained inside a zone,
750037 // used as an indirect inode list
750038 // (a pointer = 16 bits = 2 bytes).
750039 //
750040 #define INODE_MAX_INDIRECT_ZONES (SB_MAX_ZONE_SIZE/2)
750041 //----------------------------------------------------------
750042 #define INODE_MAX_REFERENCES 0xFF
750043 //----------------------------------------------------------
750044 typedef uint16_t zno_t; // Zone number.
750045 //----------------------------------------------------------
750046 // The structured type `inode_t' must be pre-declared
750047 // here, because the type sb_t, described before the
750048 // inode structure, has a member pointing to a type
750049 // `inode_t'. So, must be declared previously the type
750050 // `inode_t' as made of a type `struct inode', then the
750051 // structure `inode' can be described. But for a matter
750052 // of coherence, all other structured data declared
750053 // inside this file follow the same procedure.
750054 //
750055 typedef struct sb sb_t;
750056 typedef struct inode inode_t;
750057 typedef struct sock sock_t;
750058 typedef struct file file_t;
750059 typedef struct fd fd_t;
750060 typedef struct directory directory_t;
750061 //----------------------------------------------------------
750062 #define SB_MAX_SLOTS 16 // Handle max 16 file
750063 // systems.
750064
750065 struct sb
750066 { // File system super block:
750067 uint16_t inodes; // inodes available;
750068 uint16_t zones; // zones available (disk
750069 // size);
750070 uint16_t map_inode_blocks; // inode bit map
750071 // blocks;
750072 uint16_t map_zone_blocks; // data-zone bit map
750073 // blocks;
750074 uint16_t first_data_zone; // first data-zone;
750075 uint16_t log2_size_zone; // log_2
750076 // (size_zone/block_size);
750077 uint32_t max_file_size; // max file size in
750078 // bytes;
750079 uint16_t magic_number; // file system magic
750080 // number.
750081 // -------------------------------------------------
750082 // Extra management data, not saved inside the file
750083 // system
750084 // super block.
750085 // -------------------------------------------------
750086 dev_t device; // FS device [3]
750087 inode_t *inode_mounted_on; // [4]
750088 blksize_t blksize; // Calculated zone size.
750089 int options; // [5]
750090 uint16_t map_inode[SB_MAP_INODE_SIZE];
750091 uint16_t map_zone[SB_MAP_ZONE_SIZE];
750092 char changed;
750093 };
750094
750095 extern sb_t sb_table[SB_MAX_SLOTS];
750096 //
750097 // [3] the member `device' must be kept at the same
750098 // position, because it is used to calculate the
750099 // super block header size, saved on disk.
750100 //
750101 // [4] If this pointer is not NULL, the super block is
750102 // related to a device mounted on a directory. The
750103 // inode of such directory is recorded here. Please
750104 // note that it is type `void *', instead of type
750105 // `inode_t', because type `inode_t' is declared
750106 // after type `sb_t'.
750107 // Please note that the type `sb_t' is declared
750108 // before the type `inode_t', but this member
750109 // points to a type `inode_t'.
750110 // This is the reason because it was necessary to
750111 // declare first the type `inode_t' as made of
750112 // `struct inode', to be described later. For
750113 // coherence, all derived type made of structured
750114 // data, are first declared as structure, and then,
750115 // later, described.
750116 //
750117 // [5] Mount options can be only `MOUNT_DEFAULT' or
750118 // `MOUNT_RO', as defined inside file
750119 // `lib/sys/os32.h'.
750120 //
750121 //----------------------------------------------------------
750122 #define INODE_MAX_SLOTS (32 * OPEN_MAX)
750123 #define INODE_PIPE_BUFFER_SIZE 18 // (7 dir. + 2
750124 // ind.) * 2.
750125 //
750126 struct inode
750127 { // Inode (32 byte total):
750128 uint16_t mode; // file type and permissions;
750129 uint16_t uid; // user ID (16 bit);
750130 uint32_t size; // file size in bytes;
750131 uint32_t time; // file data modification
750132 // time;
750133 uint8_t gid; // group ID (8 bit);
750134 uint8_t links; // links to the inode;
750135 uint16_t direct[7]; // direct zones;
750136 uint16_t indirect1; // indirect zones;
750137 uint16_t indirect2; // double indirect zones.
750138 // -------------------------------------------------
750139 // Extra management data, not saved inside the disk
750140 // file system.
750141 // -------------------------------------------------
750142 sb_t *sb; // Inode's super block. [7]
750143 ino_t ino; // Inode number.
750144 sb_t *sb_attached; // [8]
750145 blkcnt_t blkcnt; // Rounded size/blksize.
750146 unsigned char references; // Run time active
750147 // references.
750148 char changed:1, // 1 == to be saved.
750149 pipe_dir:1; // 0 == read, 1 == write.
750150 unsigned char pipe_off_read; // Pipe read offset.
750151 unsigned char pipe_off_write; // Pipe write offset
750152 unsigned char pipe_ref_read; // Pipe read
750153 // references.
750154 unsigned char pipe_ref_write; // Pipe write
750155 // references
750156 };
750157
750158 extern inode_t inode_table[INODE_MAX_SLOTS];
750159 //
750160 // [7] the member `sb' must be kept at the same
750161 // position, because it is used to calculate the
750162 // inode header size, saved on disk.
750163 //
750164 // [8] If the inode is a mount point for another
750165 // device, the other super block pointer is saved
750166 // inside `sb_attached'.
750167 //
750168 //----------------------------------------------------------
750169 #define SOCK_MAX_SLOTS 64
750170 #define SOCK_MAX_QUEUE (SOCK_MAX_SLOTS/4)
750171 //
750172 struct sock
750173 {
750174 int family;
750175 int type;
750176 int protocol;
750177 h_addr_t laddr; // Local address, host byte
750178 // order.
750179 h_port_t lport; // Local port, host byte
750180 // order.
750181 h_addr_t raddr; // Remote address, host byte
750182 // order.
750183 h_port_t rport; // Remote port, host byte
750184 // order.
750185 struct
750186 {
750187 clock_t clock[IP_MAX_PACKETS]; // [9]
750188 } read;
750189 uint8_t active:1, // Is the socket used?
750190 unreach_net:1, //
750191 unreach_host:1, // ICMP unreachable status.
750192 unreach_prot:1, //
750193 unreach_port:1; //
750194 struct
750195 {
750196 uint16_t conn:4, // Connection status.
750197 can_write:1, // Can write to send_data[].
750198 can_read:1, // Can read from *recv_index.
750199 can_send:1, // Can send data.
750200 can_recv:1, // Can receive data.
750201 send_closed:1, // Closed send direction.
750202 recv_closed:1; // Closed receive direction.
750203 //
750204 uint32_t lsq[16]; // Local sequence array.
750205 uint32_t lsq_ack; // Expected acknowledge.
750206 uint32_t rsq[16]; // Remote sequence array.
750207 uint8_t lsqi:4, // Local sequence array index.
750208 rsqi:4; // Remote sequence array index.
750209 //
750210 clock_t clock; // When was last send.
750211 //
750212 uint8_t send_data[TCP_MSS - sizeof (struct tcphdr)];
750213 size_t send_size; // Size of `send_data[]'
750214 // content.
750215 int send_flags;
750216 uint8_t recv_data[TCP_MAX_DATA_SIZE]; // Data
750217 // received.
750218 size_t recv_size; // Size of `recv_data[]'
750219 // content.
750220 uint8_t *recv_index; // Read index inside
750221 // `recv_data[]'.
750222 pid_t listen_pid; // Process listening at local
750223 // port.
750224 int listen_max; // Max connection requests.
750225 int listen_queue[SOCK_MAX_QUEUE]; // [10]
750226 } tcp;
750227 };
750228 //
750229 extern sock_t sock_table[SOCK_MAX_SLOTS];
750230 //
750231 // [9] The array `read.clock[]' has the same size as
750232 // the array as `ip_tables[]', so that it can be
750233 // saved, inside the former, the clock time of a
750234 // packet read for the socket purposes.
750235 // This is necessary to know if the packet was
750236 // already managed inside the socket system, or
750237 // it is new.
750238 //
750239 // [10] When a process listen o a local port, member
750240 // `listen_pid' contains the pid number; member
750241 // `listen_max' contains the max allowed
750242 // connections that will be serviced; the array
750243 // `listen_queue[]' will contain the file
750244 // descriptors of established connections.
750245 // If `listen_queue[x]' is equal to -1, it means
750246 // that there is no file descriptor there.
750247 //
750248 //----------------------------------------------------------
750249 #define FILE_MAX_SLOTS (64 * OPEN_MAX)
750250
750251 struct file
750252 {
750253 int references;
750254 off_t offset; // File position.
750255 int oflags; // Open mode: r/w/r+w [11]
750256 inode_t *inode;
750257 sock_t *sock;
750258 };
750259
750260 extern file_t file_table[FILE_MAX_SLOTS];
750261 //
750262 // [11] the member `oflags' can get only O_RDONLY,
750263 // O_WRONLY, O_RDWR, (from header `fcntl.h')
750264 // combined with OR binary operator.
750265 //
750266 //----------------------------------------------------------
750267 struct fd
750268 {
750269 int fl_flags; // File status flags and file
750270 // access modes. [12]
750271 int fd_flags; // File descriptor flags:
750272 // currently only FD_CLOEXEC.
750273 file_t *file; // Pointer to the file table.
750274 };
750275 //
750276 // [12] the member `fl_flags' can get only O_RDONLY,
750277 // O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NOCTTY,
750278 // O_TRUNC, O_APPEND and O_NONBLOCK
750279 // (from header `fcntl.h') combined with OR
750280 // binary operator.
750281 // Options like O_DSYNC, O_RSYNC and O_SYNC are
750282 // not taken into consideration by os32.
750283 //
750284 // Please notice that each process has its own `fd'
750285 // table, embedded inside the process table.
750286 //----------------------------------------------------------
750287 struct directory
750288 { // Directory entry:
750289 uint16_t ino; // inode number;
750290 char name[NAME_MAX]; // file name.
750291 };
750292 //----------------------------------------------------------
750293 void fs_init (void);
750294 //----------------------------------------------------------
750295 int sb_inode_status (sb_t * sb, ino_t ino);
750296 sb_t *sb_mount (dev_t device, inode_t ** inode_mnt,
750297 int options);
750298 void sb_print (void);
750299 sb_t *sb_reference (dev_t device);
750300 int sb_save (sb_t * sb);
750301 int sb_zone_status (sb_t * sb, zno_t zone);
750302 //----------------------------------------------------------
750303 zno_t zone_alloc (sb_t * sb);
750304 int zone_free (sb_t * sb, zno_t zone);
750305 void zone_print (sb_t * sb, zno_t zone);
750306 int zone_read (sb_t * sb, zno_t zone, void *buffer);
750307 int zone_write (sb_t * sb, zno_t zone, void *buffer);
750308 //----------------------------------------------------------
750309 inode_t *inode_alloc (dev_t device, mode_t mode,
750310 uid_t uid, gid_t gid);
750311 int inode_check (inode_t * inode, mode_t type,
750312 int perm, uid_t uid, gid_t gid);
750313 int inode_dir_empty (inode_t * inode);
750314 ssize_t inode_file_read (inode_t * inode, off_t offset,
750315 void *buffer, size_t count,
750316 int *eof);
750317 ssize_t inode_file_write (inode_t * inode,
750318 off_t offset,
750319 const void *buffer, size_t count);
750320 int inode_free (inode_t * inode);
750321 blkcnt_t inode_fzones_read (inode_t * inode,
750322 zno_t zone_start,
750323 void *buffer, blkcnt_t blkcnt);
750324 blkcnt_t inode_fzones_write (inode_t * inode,
750325 zno_t zone_start,
750326 void *buffer, blkcnt_t blkcnt);
750327 inode_t *inode_get (dev_t device, ino_t ino);
750328 inode_t *inode_pipe_make (void);
750329 ssize_t inode_pipe_read (inode_t * inode, void *buffer,
750330 size_t count, int *eof);
750331 ssize_t inode_pipe_write (inode_t * inode,
750332 const void *buffer, size_t count);
750333 void inode_print (void);
750334 int inode_put (inode_t * inode);
750335 inode_t *inode_reference (dev_t device, ino_t ino);
750336 int inode_save (inode_t * inode);
750337 inode_t *inode_stdio_dev_make (dev_t device, mode_t mode);
750338 int inode_truncate (inode_t * inode);
750339 zno_t inode_zone (inode_t * inode, zno_t fzone, int write);
750340 //----------------------------------------------------------
750341 file_t *file_pipe_make (void);
750342 file_t *file_reference (int fno);
750343 file_t *file_stdio_dev_make (dev_t device, mode_t mode,
750344 int oflags);
750345 //----------------------------------------------------------
750346 dev_t path_device (pid_t pid, const char *path);
750347 int path_fix (char *path);
750348 int path_full (const char *path,
750349 const char *path_cwd, char *full_path);
750350 inode_t *path_inode (pid_t pid, const char *path);
750351 inode_t *path_inode_link (pid_t pid, const char *path,
750352 inode_t * inode, mode_t mode);
750353 //----------------------------------------------------------
750354 int fd_dup (pid_t pid, int fdn_old, int fdn_min);
750355 fd_t *fd_reference (pid_t pid, int *fdn);
750356 //----------------------------------------------------------
750357 //
750358 // void sock_put (sock_t *s);
750359 //
750360 #define sock_put(s) (s->active=0)
750361
750362 sock_t *sock_reference (int skn);
750363 h_port_t sock_free_port (void);
750364 //----------------------------------------------------------
750365
750366 #endif
|
|
94.5.1
kernel/fs/fd_dup.c
Si veda la sezione 93.6.1.
760001 #include <kernel/proc.h>
760002 #include <kernel/fs.h>
760003 #include <errno.h>
760004 #include <fcntl.h>
760005 //----------------------------------------------------------
760006 int
760007 fd_dup (pid_t pid, int fdn_old, int fdn_min)
760008 {
760009 proc_t *ps;
760010 int fdn_new;
760011 //
760012 // Verify argument.
760013 //
760014 if (fdn_min < 0 || fdn_min >= OPEN_MAX)
760015 {
760016 errset (EINVAL); // Invalid argument.
760017 return (-1);
760018 }
760019 //
760020 // Get process.
760021 //
760022 ps = proc_reference (pid);
760023 //
760024 // Verify if `fdn_old' is a valid value.
760025 //
760026 if (fdn_old < 0 ||
760027 fdn_old >= OPEN_MAX || ps->fd[fdn_old].file == NULL)
760028 {
760029 errset (EBADF); // Bad file descriptor.
760030 return (-1);
760031 }
760032 //
760033 // Find the first free slot and duplicate the file
760034 // descriptor.
760035 //
760036 for (fdn_new = fdn_min; fdn_new < OPEN_MAX; fdn_new++)
760037 {
760038 if (ps->fd[fdn_new].file == NULL)
760039 {
760040 ps->fd[fdn_new].fl_flags =
760041 ps->fd[fdn_old].fl_flags;
760042 ps->fd[fdn_new].fd_flags =
760043 ps->fd[fdn_old].fd_flags & ~FD_CLOEXEC;
760044 ps->fd[fdn_new].file = ps->fd[fdn_old].file;
760045 ps->fd[fdn_new].file->references++;
760046 return (fdn_new);
760047 }
760048 }
760049 //
760050 // No fd slot available.
760051 //
760052 errset (EMFILE); // Too many open files.
760053 return (-1);
760054 }
|
|
94.5.2
kernel/fs/fd_reference.c
Si veda la sezione 93.6.2.
770001 #include <kernel/proc.h>
770002 #include <kernel/lib_k.h>
770003 #include <errno.h>
770004 //----------------------------------------------------------
770005 fd_t *
770006 fd_reference (pid_t pid, int *fdn)
770007 {
770008 proc_t *ps;
770009 //
770010 // Get process.
770011 //
770012 ps = proc_reference (pid);
770013 //
770014 // See what to do.
770015 //
770016 if (*fdn < 0)
770017 {
770018 //
770019 // Find the first free slot.
770020 //
770021 for (*fdn = 0; *fdn < OPEN_MAX; (*fdn)++)
770022 {
770023 if (ps->fd[*fdn].file == NULL)
770024 {
770025 return (&(ps->fd[*fdn]));
770026 }
770027 }
770028 *fdn = -1;
770029 return (NULL);
770030 }
770031 else
770032 {
770033 if (*fdn < OPEN_MAX)
770034 {
770035 //
770036 // Might return even a free file descriptor.
770037 //
770038 return (&(ps->fd[*fdn]));
770039 }
770040 else
770041 {
770042 return (NULL);
770043 }
770044 }
770045 }
|
|
94.5.3
kernel/fs/file_pipe_make.c
Si veda la sezione 93.6.4.
780001 #include <kernel/proc.h>
780002 #include <errno.h>
780003 #include <fcntl.h>
780004 //----------------------------------------------------------
780005 file_t *
780006 file_pipe_make (void)
780007 {
780008 inode_t *inode;
780009 file_t *file;
780010 //
780011 // Try to allocate a device inode.
780012 //
780013 inode = inode_pipe_make ();
780014 if (inode == NULL)
780015 {
780016 //
780017 // Variable `errno' is already set by
780018 // `inode_stdio_dev_make()'.
780019 //
780020 errset (errno);
780021 return (NULL);
780022 }
780023 //
780024 // Inode allocated: need to allocate the system file
780025 // item.
780026 //
780027 file = file_reference (-1);
780028 if (file == NULL)
780029 {
780030 //
780031 // Remove the inode and return an error.
780032 //
780033 inode_put (inode);
780034 errset (ENFILE); // Too many files open in
780035 // system.
780036 return (NULL);
780037 }
780038 //
780039 // Fill with data the system file item.
780040 //
780041 file->references = 2;
780042 file->oflags = (O_RDONLY | O_WRONLY);
780043 file->inode = inode;
780044 //
780045 // Return system file pointer.
780046 //
780047 return (file);
780048 }
|
|
94.5.4
kernel/fs/file_reference.c
Si veda la sezione 93.6.5.
790001 #include <kernel/proc.h>
790002 #include <errno.h>
790003 #include <fcntl.h>
790004 //----------------------------------------------------------
790005 file_t *
790006 file_reference (int fno)
790007 {
790008 //
790009 // Check type of request.
790010 //
790011 if (fno < 0)
790012 {
790013 //
790014 // Find a free slot.
790015 //
790016 for (fno = 0; fno < FILE_MAX_SLOTS; fno++)
790017 {
790018 if (file_table[fno].references <= 0)
790019 {
790020 return (&file_table[fno]);
790021 }
790022 }
790023 return (NULL);
790024 }
790025 else if (fno > FILE_MAX_SLOTS)
790026 {
790027 return (NULL);
790028 }
790029 else
790030 {
790031 return (&file_table[fno]);
790032 }
790033 }
|
|
94.5.5
kernel/fs/file_stdio_dev_make.c
Si veda la sezione 93.6.6.
800001 #include <kernel/proc.h>
800002 #include <errno.h>
800003 #include <fcntl.h>
800004 //----------------------------------------------------------
800005 file_t *
800006 file_stdio_dev_make (dev_t device, mode_t mode, int oflags)
800007 {
800008 inode_t *inode;
800009 file_t *file;
800010 //
800011 // Try to allocate a device inode.
800012 //
800013 inode = inode_stdio_dev_make (device, mode);
800014 if (inode == NULL)
800015 {
800016 //
800017 // Variable `errno' is already set by
800018 // `inode_stdio_dev_make()'.
800019 //
800020 errset (errno);
800021 return (NULL);
800022 }
800023 //
800024 // Inode allocated: need to allocate the system file
800025 // item.
800026 //
800027 file = file_reference (-1);
800028 if (file == NULL)
800029 {
800030 //
800031 // Remove the inode and return an error.
800032 //
800033 inode_put (inode);
800034 errset (ENFILE); // Too many files open in
800035 // system.
800036 return (NULL);
800037 }
800038 //
800039 // Fill with data the system file item.
800040 //
800041 file->references = 1;
800042 file->oflags = (oflags & (O_RDONLY | O_WRONLY));
800043 file->inode = inode;
800044 //
800045 // Return system file pointer.
800046 //
800047 return (file);
800048 }
|
|
94.5.6
kernel/fs/fs_init.c
Si veda la sezione 93.6.3.
810001 #include <kernel/fs.h>
810002 #include <string.h>
810003 //----------------------------------------------------------
810004 void
810005 fs_init (void)
810006 {
810007 int s;
810008 int i;
810009 int f;
810010 //
810011 for (s = 0; s < SB_MAX_SLOTS; s++)
810012 {
810013 sb_table[s].device = 0;
810014 sb_table[s].inode_mounted_on = NULL;
810015 }
810016 //
810017 for (i = 0; i < INODE_MAX_SLOTS; i++)
810018 {
810019 inode_table[i].references = 0;
810020 }
810021 //
810022 for (f = 0; f < FILE_MAX_SLOTS; f++)
810023 {
810024 file_table[f].references = 0;
810025 file_table[f].inode = NULL;
810026 file_table[f].sock = NULL;
810027 }
810028 //
810029 // Reset the socket table with 0x00.
810030 //
810031 memset (sock_table, 0x00, sizeof (sock_table));
810032 }
|
|
94.5.7
kernel/fs/fs_public.c
Si veda la sezione 93.6.
820001 #include <kernel/fs.h>
820002 //----------------------------------------------------------
820003 sb_t sb_table[SB_MAX_SLOTS];
820004 file_t file_table[FILE_MAX_SLOTS];
820005 inode_t inode_table[INODE_MAX_SLOTS];
820006 sock_t sock_table[SOCK_MAX_SLOTS];
820007 //----------------------------------------------------------
|
|
94.5.8
kernel/fs/inode_alloc.c
Si veda la sezione 93.6.7.
830001 #include <kernel/fs.h>
830002 #include <errno.h>
830003 #include <kernel/lib_k.h>
830004 #include <kernel/lib_s.h>
830005 //----------------------------------------------------------
830006 inode_t *
830007 inode_alloc (dev_t device, mode_t mode, uid_t uid,
830008 gid_t gid)
830009 {
830010 sb_t *sb;
830011 inode_t *inode;
830012 int m; // Index inside the inode map.
830013 int map_element;
830014 int map_bit;
830015 int map_mask;
830016 ino_t ino;
830017 //
830018 // Check for arguments.
830019 //
830020 if (mode == 0)
830021 {
830022 errset (EINVAL); // Invalid argument.
830023 return (NULL);
830024 }
830025 //
830026 // Get the super block from the known device.
830027 //
830028 sb = sb_reference (device);
830029 if (sb == NULL)
830030 {
830031 errset (ENODEV); // No such device.
830032 return (NULL);
830033 }
830034 //
830035 // Find a free inode.
830036 //
830037 while (1)
830038 {
830039 //
830040 // Scan the inode bit map, to find a free inode
830041 // for new allocation.
830042 //
830043 for (m = 0; m < (SB_MAP_INODE_SIZE * 16); m++)
830044 {
830045 map_element = m / 16;
830046 map_bit = m % 16;
830047 map_mask = 1 << map_bit;
830048 if (!(sb->map_inode[map_element] & map_mask))
830049 {
830050 //
830051 // Found a free element: change the map
830052 // to
830053 // allocate the inode.
830054 //
830055 sb->map_inode[map_element] |= map_mask;
830056 sb->changed = 1;
830057 ino = m; // Found a free inode:
830058 break; // exit the scan loop.
830059 }
830060 }
830061 //
830062 // Check if the scan was successful.
830063 //
830064 if (ino == 0)
830065 {
830066 errset (ENOSPC); // No space left on
830067 // device.
830068 return (NULL);
830069 }
830070 //
830071 // The inode was allocated inside the map in
830072 // memory.
830073 //
830074 inode = inode_get (device, ino);
830075 if (inode == NULL)
830076 {
830077 errset (ENFILE); // Too many files open
830078 // in system.
830079 return (NULL);
830080 }
830081 //
830082 // Verify if the inode is really free: if it
830083 // isn't, must save
830084 // it to disk.
830085 //
830086 if (inode->size > 0 || inode->links > 0)
830087 {
830088 //
830089 // Strange: should not have a size! Check if
830090 // there are even
830091 // links. Please note that 255 links (that
830092 // is -1) is to be
830093 // considered a free inode, marked in a
830094 // special way for some
830095 // unknown reason. Currently, `LINK_MAX' is
830096 // equal to 254,
830097 // for that reason.
830098 //
830099 if (inode->links > 0 && inode->links < LINK_MAX)
830100 {
830101 //
830102 // Tell something.
830103 //
830104 k_printf ("kernel alert: device %04x: "
830105 "found \"free\" inode %i "
830106 "that still has size %i "
830107 "and %i links!\n",
830108 device, ino, inode->size,
830109 inode->links);
830110 //
830111 // The inode must be set again to free,
830112 // inside
830113 // the bit map.
830114 //
830115 map_element = ino / 16;
830116 map_bit = ino % 16;
830117 map_mask = 1 << map_bit;
830118 sb->map_inode[map_element] &= ~map_mask;
830119 sb->changed = 1;
830120 //
830121 // Try to fix: reset all to zero.
830122 //
830123 inode->mode = 0;
830124 inode->uid = 0;
830125 inode->gid = 0;
830126 inode->time = 0;
830127 inode->links = 0;
830128 inode->size = 0;
830129 inode->direct[0] = 0;
830130 inode->direct[1] = 0;
830131 inode->direct[2] = 0;
830132 inode->direct[3] = 0;
830133 inode->direct[4] = 0;
830134 inode->direct[5] = 0;
830135 inode->direct[6] = 0;
830136 inode->indirect1 = 0;
830137 inode->indirect2 = 0;
830138 inode->changed = 1;
830139 //
830140 // Save fixed inode to disk.
830141 //
830142 inode_put (inode);
830143 continue;
830144 }
830145 else
830146 {
830147 //
830148 // Truncate the inode, save and break.
830149 //
830150 inode_truncate (inode);
830151 inode_save (inode);
830152 break;
830153 }
830154 }
830155 else
830156 {
830157 //
830158 // Considering free the inode found.
830159 //
830160 break;
830161 }
830162 }
830163 //
830164 // Put data inside the inode.
830165 //
830166 inode->mode = mode;
830167 inode->uid = uid;
830168 inode->gid = gid;
830169 inode->size = 0;
830170 inode->time = s_time ((pid_t) 0, NULL);
830171 inode->links = 0;
830172 inode->changed = 1;
830173 //
830174 // Save the inode.
830175 //
830176 inode_save (inode);
830177 //
830178 // Return the inode pointer.
830179 //
830180 return (inode);
830181 }
|
|
94.5.9
kernel/fs/inode_check.c
Si veda la sezione 93.6.8.
840001 #include <kernel/fs.h>
840002 #include <errno.h>
840003 #include <kernel/lib_k.h>
840004 //----------------------------------------------------------
840005 int
840006 inode_check (inode_t * inode, mode_t type, int perm,
840007 uid_t uid, gid_t gid)
840008 {
840009 //
840010 // Ensure that the variable `type' has only the
840011 // requested file type.
840012 //
840013 type = (type & S_IFMT);
840014 //
840015 // Check inode argument.
840016 //
840017 if (inode == NULL)
840018 {
840019 errset (EINVAL); // Invalid argument.
840020 return (-1);
840021 }
840022 //
840023 // The inode is not NULL: verify that the inode is
840024 // of a type
840025 // allowed (the parameter `type' can hold more than
840026 // one
840027 // possibility).
840028 //
840029 if (!(inode->mode & type))
840030 {
840031 errset (E_FILE_TYPE); // The file type is
840032 // not
840033 return (-1); // the expected one.
840034 }
840035 //
840036 // The file type is correct.
840037 //
840038 if (inode->uid != 0 && uid == 0)
840039 {
840040 return (0); // The root user has all
840041 // permissions.
840042 }
840043 //
840044 // The user is not root or the inode is owned by
840045 // root.
840046 //
840047 if (inode->uid == uid)
840048 {
840049 //
840050 // The user own the inode and must check user
840051 // permissions.
840052 //
840053 perm = (perm << 6);
840054 if ((inode->mode & perm) ^ perm)
840055 {
840056 errset (EACCES); // Permission denied.
840057 return (-1);
840058 }
840059 else
840060 {
840061 return (0);
840062 }
840063 }
840064 //
840065 // The user does not own the inode: the group
840066 // permissions are
840067 // checked.
840068 //
840069 if (inode->gid == gid)
840070 {
840071 //
840072 // The group own the inode and must check user
840073 // permissions.
840074 //
840075 perm = (perm << 3);
840076 if ((inode->mode & perm) ^ perm)
840077 {
840078 errset (EACCES); // Permission denied.
840079 return (-1);
840080 }
840081 else
840082 {
840083 return (0);
840084 }
840085 }
840086 //
840087 // The user and the group do not own the inode: the
840088 // other
840089 // permissions are checked.
840090 //
840091 if ((inode->mode & perm) ^ perm)
840092 {
840093 errset (EACCES); // Permission denied.
840094 return (-1);
840095 }
840096 else
840097 {
840098 return (0);
840099 }
840100 }
|
|
94.5.10
kernel/fs/inode_dir_empty.c
Si veda la sezione 93.6.9.
850001 #include <kernel/fs.h>
850002 #include <errno.h>
850003 #include <kernel/lib_k.h>
850004 //----------------------------------------------------------
850005 int
850006 inode_dir_empty (inode_t * inode)
850007 {
850008 off_t start;
850009 char buffer[SB_MAX_ZONE_SIZE];
850010 directory_t *dir;
850011 ssize_t size_read;
850012 int d; // Directory buffer index.
850013 //
850014 // Check argument: must be a directory.
850015 //
850016 if (inode == NULL || !S_ISDIR (inode->mode))
850017 {
850018 errset (EINVAL); // Invalid argument.
850019 return (0); // false
850020 }
850021 //
850022 // Read the directory content: if an item is present
850023 // (except `.' and
850024 // `..'), the directory is not empty.
850025 //
850026 for (start = 0;
850027 start < inode->size; start += inode->sb->blksize)
850028 {
850029 size_read =
850030 inode_file_read (inode, start, buffer,
850031 inode->sb->blksize, NULL);
850032 if (size_read < sizeof (directory_t))
850033 {
850034 break;
850035 }
850036 //
850037 // Scan the directory portion just read.
850038 //
850039 dir = (directory_t *) buffer;
850040 //
850041 for (d = 0; d < size_read;
850042 d += (sizeof (directory_t)), dir++)
850043 {
850044 if (dir->ino != 0 &&
850045 strncmp (dir->name, ".", NAME_MAX) != 0
850046 && strncmp (dir->name, "..", NAME_MAX) != 0)
850047 {
850048 //
850049 // There is an item and the directory is
850050 // not empty.
850051 //
850052 return (0); // false
850053 }
850054 }
850055 }
850056 //
850057 // Nothing was found; good!
850058 //
850059 return (1); // true
850060 }
|
|
94.5.11
kernel/fs/inode_file_read.c
Si veda la sezione 93.6.10.
860001 #include <kernel/fs.h>
860002 #include <errno.h>
860003 #include <kernel/lib_k.h>
860004 //----------------------------------------------------------
860005 ssize_t
860006 inode_file_read (inode_t * inode, off_t offset,
860007 void *buffer, size_t count, int *eof)
860008 {
860009 unsigned char *destination = (unsigned char *) buffer;
860010 unsigned char zone_buffer[SB_MAX_ZONE_SIZE];
860011 blkcnt_t blkcnt_read;
860012 off_t off_fzone; // File zone offset.
860013 off_t off_buffer; // Destination buffer offset.
860014 ssize_t size_read; // Byte transfer counter.
860015 zno_t fzone;
860016 off_t off_end;
860017 //
860018 // The inode pointer must be valid, and
860019 // the start byte must be positive.
860020 //
860021 if (inode == NULL || offset < 0)
860022 {
860023 errset (EINVAL); // Invalid argument.
860024 return ((ssize_t) - 1);
860025 }
860026 //
860027 // Check if the start address is inside the file
860028 // size. This is not
860029 // an error, but zero bytes are read and `*eof' is
860030 // set. Otherwise,
860031 // `*eof' is reset.
860032 //
860033 if (offset >= inode->size)
860034 {
860035 (eof != NULL) ? *eof = 1 : 0;
860036 return (0);
860037 }
860038 else
860039 {
860040 (eof != NULL) ? *eof = 0 : 0;
860041 }
860042 //
860043 // Adjust, if necessary, the size of read, because
860044 // it cannot be
860045 // larger than the actual file size. The variable
860046 // `off_end' is
860047 // used to calculate the position *after* the
860048 // requested read.
860049 // Remember that the first file position is byte
860050 // zero; so,
860051 // the byte index inside the file goes from zero to
860052 // inode->size -1.
860053 //
860054 off_end = offset;
860055 off_end += count;
860056 if (off_end > inode->size)
860057 {
860058 count = (inode->size - offset);
860059 }
860060 //
860061 // Read the first file-zone inside the zone buffer.
860062 //
860063 fzone = offset / inode->sb->blksize;
860064 off_fzone = offset % inode->sb->blksize;
860065 blkcnt_read =
860066 inode_fzones_read (inode, fzone, zone_buffer,
860067 (blkcnt_t) 1);
860068 if (blkcnt_read <= 0)
860069 {
860070 //
860071 // Sorry!
860072 //
860073
860074 k_printf
860075 ("inode_fzones_read (inode, fzone %i,... )\n",
860076 fzone);
860077
860078 errset (EUNKNOWN);
860079 return (0); // Zero bytes read!
860080 }
860081 //
860082 // The first file-zone was read: copy it inside the
860083 // destination
860084 // buffer and continue reading the other zones
860085 // needed. Variables
860086 // `off_buffer' (destination buffer index) and
860087 // `size_read' (copy
860088 // byte counter) must be reset here. Variable
860089 // `off_fzone' is already
860090 // set with the initial offset inside `zone_buffer'.
860091 //
860092 off_buffer = 0;
860093 size_read = 0;
860094 //
860095 while (count)
860096 {
860097 //
860098 // Copy the zone buffer into the destination.
860099 // Variables
860100 // `off_fzone', `off_buffer' and `size_read'
860101 // must not be
860102 // initialized inside the loop.
860103 //
860104 for (;
860105 off_fzone < inode->sb->blksize && count > 0;
860106 off_fzone++, off_buffer++, size_read++,
860107 count--, offset++)
860108 {
860109 destination[off_buffer] = zone_buffer[off_fzone];
860110 }
860111 //
860112 // If not all the bytes are copied, read the
860113 // next file-zone.
860114 //
860115 if (count)
860116 {
860117 //
860118 // Read another file-zone inside the zone
860119 // buffer.
860120 // Again, the function `inode_fzones_read()'
860121 // might
860122 // return a null pointer, but the variable
860123 // `errno' tells if
860124 // it is really an error. For this reason,
860125 // the variable
860126 // `errno' must be reset before the read,
860127 // and checked after
860128 // it.
860129 //
860130 fzone = offset / inode->sb->blksize;
860131 off_fzone = offset % inode->sb->blksize;
860132 blkcnt_read =
860133 inode_fzones_read (inode, fzone,
860134 zone_buffer, (blkcnt_t) 1);
860135 if (blkcnt_read <= 0)
860136 {
860137 //
860138 // Sorry: only `size_read' bytes read!
860139 //
860140 errset (EUNKNOWN);
860141 return (size_read);
860142 }
860143 }
860144 }
860145 //
860146 // The requested size was read completely.
860147 //
860148 return (size_read);
860149 }
|
|
94.5.12
kernel/fs/inode_file_write.c
Si veda la sezione 93.6.11.
870001 #include <kernel/fs.h>
870002 #include <errno.h>
870003 #include <kernel/lib_k.h>
870004 //----------------------------------------------------------
870005 ssize_t
870006 inode_file_write (inode_t * inode, off_t offset,
870007 const void *buffer, size_t count)
870008 {
870009 unsigned char *buffer_source = (unsigned char *) buffer;
870010 unsigned char buffer_zone[SB_MAX_ZONE_SIZE];
870011 off_t off_fzone; // File zone offset.
870012 off_t off_source; // Source buffer offset.
870013 ssize_t size_copied; // Byte transfer counter.
870014 ssize_t size_written; // Byte written counter.
870015 zno_t fzone;
870016 zno_t zone;
870017 blkcnt_t blkcnt_read;
870018 int status;
870019 //
870020 // The inode pointer must be valid, and
870021 // the start byte must be positive.
870022 //
870023 if (inode == NULL || offset < 0)
870024 {
870025 errset (EINVAL); // Invalid argument.
870026 return ((ssize_t) - 1);
870027 }
870028 //
870029 // Read a zone, modify it with the source buffer,
870030 // then write it back
870031 // and continue reading and writing other zones if
870032 // needed.
870033 //
870034 for (size_written = 0, off_source = 0, size_copied =
870035 0; count > 0; size_written += size_copied)
870036 {
870037 //
870038 // Read the next file-zone inside the zone
870039 // buffer: the function
870040 // `inode_zone()' is used to create
870041 // automatically the zone, if
870042 // it does not exist.
870043 //
870044 fzone = offset / inode->sb->blksize;
870045 off_fzone = offset % inode->sb->blksize;
870046 zone = inode_zone (inode, fzone, 1);
870047 if (zone == 0)
870048 {
870049 //
870050 // Return previously written bytes. The
870051 // variable `errno' is
870052 // already set by `inode_zone()'.
870053 //
870054 return (size_written);
870055 }
870056 blkcnt_read =
870057 inode_fzones_read (inode, fzone, buffer_zone,
870058 (blkcnt_t) 1);
870059 if (blkcnt_read <= 0)
870060 {
870061 //
870062 // Even if the value is zero, there is a
870063 // problem reading the
870064 // zone to be overwritten (because
870065 // `inode_zone()' should
870066 // have already created such zone). The
870067 // variable `errno' is
870068 // already set by `inode_fzones_read()'.
870069 //
870070 return ((ssize_t) - 1);
870071 }
870072 //
870073 // The zone was successfully loaded inside the
870074 // buffer: overwrite
870075 // the zone buffer with the source buffer.
870076 //
870077 for (size_copied = 0;
870078 off_fzone < inode->sb->blksize && count > 0;
870079 off_fzone++, off_source++, size_copied++,
870080 count--, offset++)
870081 {
870082 buffer_zone[off_fzone] =
870083 buffer_source[off_source];
870084 }
870085 //
870086 // Save the zone.
870087 //
870088 status = zone_write (inode->sb, zone, buffer_zone);
870089 if (status != 0)
870090 {
870091 //
870092 // Cannot save the zone: return the size
870093 // already written.
870094 // The variable `errno' is already set by
870095 // `zone_write()'.
870096 //
870097 return (size_written);
870098 }
870099 //
870100 // Zone saved: update the file size if necessary
870101 // (and the inode
870102 // too).
870103 //
870104 if (inode->size <= offset)
870105 {
870106 inode->size = offset;
870107 inode->changed = 1;
870108 inode_save (inode);
870109 }
870110 }
870111 //
870112 // All done successfully: return the value.
870113 //
870114 return (size_written);
870115 }
|
|
94.5.13
kernel/fs/inode_free.c
Si veda la sezione 93.6.12.
880001 #include <kernel/fs.h>
880002 #include <errno.h>
880003 #include <kernel/lib_k.h>
880004 //----------------------------------------------------------
880005 int
880006 inode_free (inode_t * inode)
880007 {
880008 int map_element;
880009 int map_bit;
880010 int map_mask;
880011 //
880012 if (inode == NULL)
880013 {
880014 errset (EINVAL); // Invalid argument.
880015 return (-1);
880016 }
880017 //
880018 map_element = inode->ino / 16;
880019 map_bit = inode->ino % 16;
880020 map_mask = 1 << map_bit;
880021 //
880022 if (inode->sb->map_inode[map_element] & map_mask)
880023 {
880024 inode->sb->map_inode[map_element] -= map_mask;
880025 inode->sb->changed = 1;
880026 }
880027 //
880028 inode->mode = 0;
880029 inode->uid = 0;
880030 inode->gid = 0;
880031 inode->size = 0;
880032 inode->time = 0;
880033 inode->links = 0;
880034 inode->changed = 1;
880035 inode->references = 0;
880036 //
880037 return (inode_save (inode));
880038 }
|
|
94.5.14
kernel/fs/inode_fzones_read.c
Si veda la sezione 93.6.13.
890001 #include <kernel/fs.h>
890002 #include <errno.h>
890003 #include <kernel/lib_k.h>
890004 //----------------------------------------------------------
890005 blkcnt_t
890006 inode_fzones_read (inode_t * inode, zno_t zone_start,
890007 void *buffer, blkcnt_t blkcnt)
890008 {
890009 unsigned char *destination = (unsigned char *) buffer;
890010 int status; // `zone_read()' return value.
890011 blkcnt_t blkcnt_read; // Zone counter/index.
890012 zno_t zone;
890013 zno_t fzone;
890014 //
890015 // Read the zones into the destination buffer.
890016 //
890017 for (blkcnt_read = 0, fzone = zone_start;
890018 blkcnt_read < blkcnt; blkcnt_read++, fzone++)
890019 {
890020 //
890021 // Calculate the zone number, from the
890022 // file-zone, reading the
890023 // inode. If a zone is not really allocated, the
890024 // result is zero
890025 // and is valid.
890026 //
890027 zone = inode_zone (inode, fzone, 0);
890028 if (zone == ((zno_t) - 1))
890029 {
890030 //
890031 // This is an error. Return the read zones
890032 // quantity.
890033 //
890034 errset (EUNKNOWN);
890035 return (blkcnt_read);
890036 }
890037 //
890038 // Update the destination buffer pointer.
890039 //
890040 destination += (blkcnt_read * inode->sb->blksize);
890041 //
890042 // Read the zone inside the destination buffer,
890043 // but if the zone
890044 // is zero, a zeroed zone must be filled.
890045 //
890046 if (zone == 0)
890047 {
890048 memset (destination, 0,
890049 (size_t) inode->sb->blksize);
890050 }
890051 else
890052 {
890053 status = zone_read (inode->sb, zone, destination);
890054 if (status != 0)
890055 {
890056 //
890057 // Could not read the requested zone:
890058 // return the zones
890059 // read correctly.
890060 //
890061 errset (EIO); // I/O error.
890062 return (blkcnt_read);
890063 }
890064 }
890065 }
890066 //
890067 // All zones read correctly inside the buffer.
890068 //
890069 return (blkcnt_read);
890070 }
|
|
94.5.15
kernel/fs/inode_fzones_write.c
Si veda la sezione 93.6.13.
900001 #include <kernel/fs.h>
900002 #include <errno.h>
900003 #include <kernel/lib_k.h>
900004 //----------------------------------------------------------
900005 blkcnt_t
900006 inode_fzones_write (inode_t * inode, zno_t zone_start,
900007 void *buffer, blkcnt_t blkcnt)
900008 {
900009 unsigned char *source = (unsigned char *) buffer;
900010 int status; // `zone_read()' return value.
900011 blkcnt_t blkcnt_written; // Written zones
900012 // counter.
900013 zno_t zone;
900014 zno_t fzone;
900015 //
900016 // Write the zones into the destination buffer.
900017 //
900018 for (blkcnt_written = 0, fzone = zone_start;
900019 blkcnt_written < blkcnt; blkcnt_written++, fzone++)
900020 {
900021 //
900022 // Find real zone from file-zone.
900023 //
900024 zone = inode_zone (inode, fzone, 1);
900025 if (zone == 0 || zone == ((zno_t) - 1))
900026 {
900027 //
900028 // Function `inode_zone()' should allocate
900029 // automatically
900030 // a missing zone and should return a valid
900031 // zone or
900032 // (zno_t) -1. Anyway, even if a zero zone
900033 // is returned,
900034 // it is an error. Return the
900035 // `blkcnt_written' value.
900036 //
900037 return (blkcnt_written);
900038 }
900039 //
900040 // Update the source buffer pointer for the next
900041 // zone write.
900042 //
900043 source += (blkcnt_written * inode->sb->blksize);
900044 //
900045 // Write the zone from the buffer content.
900046 //
900047 status = zone_write (inode->sb, zone, source);
900048 if (status != 0)
900049 {
900050 //
900051 // Cannot write the zone. Return
900052 // `size_written_zone' value.
900053 //
900054 return (blkcnt_written);
900055 }
900056 }
900057 //
900058 // All zones read correctly inside the buffer.
900059 //
900060 return (blkcnt_written);
900061 }
|
|
94.5.16
kernel/fs/inode_get.c
Si veda la sezione 93.6.15.
910001 #include <kernel/fs.h>
910002 #include <errno.h>
910003 #include <kernel/lib_k.h>
910004 #include <kernel/dev.h>
910005 //----------------------------------------------------------
910006 inode_t *
910007 inode_get (dev_t device, ino_t ino)
910008 {
910009 sb_t *sb;
910010 inode_t *inode;
910011 unsigned long int start;
910012 size_t size;
910013 ssize_t n;
910014 int status;
910015 //
910016 // Verify if the root file system inode was
910017 // requested.
910018 //
910019 if (device == 0 && ino == 1)
910020 {
910021 //
910022 // Get root file system inode.
910023 //
910024 inode = inode_reference (device, ino);
910025 if (inode == NULL)
910026 {
910027 //
910028 // The file system root directory inode is
910029 // not yet loaded:
910030 // get the first super block.
910031 //
910032 sb = sb_reference ((dev_t) 0);
910033 if (sb == NULL || sb->device == 0)
910034 {
910035 //
910036 // This error should never happen.
910037 //
910038 errset (EUNKNOWN); // Unknown
910039 // error.
910040 return (NULL);
910041 }
910042 //
910043 // Load the file system root directory inode
910044 // (recursive
910045 // call).
910046 //
910047 inode = inode_get (sb->device, (ino_t) 1);
910048 if (inode == NULL)
910049 {
910050 //
910051 // This error should never happen.
910052 //
910053 errset (EUNKNOWN); // Unknown
910054 // error.
910055 return (NULL);
910056 }
910057 //
910058 // Return the directory inode.
910059 //
910060 return (inode);
910061 }
910062 else
910063 {
910064 //
910065 // The file system root directory inode is
910066 // already
910067 // available.
910068 //
910069 if (inode->references >= INODE_MAX_REFERENCES)
910070 {
910071 errset (ENFILE); // Too many files open
910072 // in system.
910073 return (NULL);
910074 }
910075 else
910076 {
910077 inode->references++;
910078 return (inode);
910079 }
910080 }
910081 }
910082 //
910083 // A common device-inode pair was requested: try to
910084 // find an already
910085 // cached inode.
910086 //
910087 inode = inode_reference (device, ino);
910088 if (inode != NULL)
910089 {
910090 if (inode->references >= INODE_MAX_REFERENCES)
910091 {
910092 errset (ENFILE); // Too many files open
910093 // in system.
910094 return (NULL);
910095 }
910096 else
910097 {
910098 inode->references++;
910099 return (inode);
910100 }
910101 }
910102 //
910103 // The inode is not yet available: get super block.
910104 //
910105 sb = sb_reference (device);
910106 if (sb == NULL)
910107 {
910108 errset (ENODEV); // No such device.
910109 return (NULL);
910110 }
910111 //
910112 // The super block is available, but the inode is
910113 // not yet cached.
910114 // Verify if the inode map reports it as allocated.
910115 //
910116 status = sb_inode_status (sb, ino);
910117 if (!status)
910118 {
910119 //
910120 // The inode is not allocated and cannot be
910121 // loaded.
910122 //
910123 errset (ENOENT); // No such file or directory.
910124 return (NULL);
910125 }
910126 //
910127 // The inode was not already cached, but is
910128 // considered as allocated
910129 // inside the inode map. Find a free slot to load
910130 // the inode inside
910131 // the inode table (in memory).
910132 //
910133 inode = inode_reference ((dev_t) - 1, (ino_t) - 1);
910134 if (inode == NULL)
910135 {
910136 errset (ENFILE); // Too many files open in
910137 // system.
910138 return (NULL);
910139 }
910140 //
910141 // A free inode slot was found. The inode must be
910142 // loaded.
910143 // Calculate the memory inode size, to be saved
910144 // inside the file
910145 // system: the administrative inode data, as it is
910146 // saved inside
910147 // the file system. The `inode_t' type is bigger
910148 // than the real
910149 // inode administrative size, because it contains
910150 // more data, that is
910151 // not saved on disk.
910152 //
910153 size = offsetof (inode_t, sb);
910154 //
910155 // Calculating start position for read.
910156 //
910157 // [1] Boot block.
910158 // [2] Super block.
910159 // [3] Inode bit map.
910160 // [4] Zone bit map.
910161 // [5] Previous inodes: consider that the inode zero
910162 // is
910163 // present in the inode map, but not in the inode
910164 // table.
910165 //
910166 start = 1024; // [1]
910167 start += 1024; // [2]
910168 start += (sb->map_inode_blocks * 1024); // [3]
910169 start += (sb->map_zone_blocks * 1024); // [4]
910170 start += ((ino - 1) * size); // [5]
910171 //
910172 // Read inode from disk.
910173 //
910174 n =
910175 dev_io ((pid_t) - 1, device, DEV_READ, start,
910176 inode, size, NULL);
910177 if (n != size)
910178 {
910179 errset (EIO); // I/O error.
910180 return (NULL);
910181 }
910182 //
910183 // The inode was read: add some data to the working
910184 // copy in memory.
910185 //
910186 inode->sb = sb;
910187 inode->sb_attached = NULL;
910188 inode->ino = ino;
910189 inode->references = 1;
910190 inode->changed = 0;
910191 //
910192 inode->blkcnt = inode->size;
910193 inode->blkcnt /= sb->blksize;
910194 if (inode->size % sb->blksize)
910195 {
910196 inode->blkcnt++;
910197 }
910198 //
910199 inode->pipe_dir = 1; // Pipes must start with
910200 // write.
910201 inode->pipe_off_read = 0;
910202 inode->pipe_off_write = 0;
910203 inode->pipe_ref_read = 0;
910204 inode->pipe_ref_write = 0;
910205 //
910206 // Return the inode pointer.
910207 //
910208 return (inode);
910209 }
|
|
94.5.17
kernel/fs/inode_pipe_make.c
Si veda la sezione 93.6.16.
920001 #include <kernel/fs.h>
920002 #include <sys/stat.h>
920003 #include <errno.h>
920004 #include <kernel/lib_k.h>
920005 #include <kernel/lib_s.h>
920006 //----------------------------------------------------------
920007 inode_t *
920008 inode_pipe_make (void)
920009 {
920010 inode_t *inode;
920011 //
920012 // Find a free inode.
920013 //
920014 inode = inode_reference ((dev_t) - 1, (ino_t) - 1);
920015 if (inode == NULL)
920016 {
920017 //
920018 // No free slot available.
920019 //
920020 errset (ENFILE); // Too many files open in
920021 // system.
920022 return (NULL);
920023 }
920024 //
920025 // Put data inside the inode. Please note that
920026 // `inode->ino' must be
920027 // zero, because it is necessary to recognize it as
920028 // an internal
920029 // inode with no file system. Otherwise, with a
920030 // value different than
920031 // zero, `inode_put()' will try to remove it. [*]
920032 //
920033 inode->mode = S_IFIFO;
920034 inode->uid = 0;
920035 inode->gid = 0;
920036 inode->size = 0;
920037 inode->time = 0;
920038 inode->links = 0;
920039 inode->direct[0] = 0;
920040 inode->direct[1] = 0;
920041 inode->direct[2] = 0;
920042 inode->direct[3] = 0;
920043 inode->direct[4] = 0;
920044 inode->direct[5] = 0;
920045 inode->direct[6] = 0;
920046 inode->indirect1 = 0;
920047 inode->indirect2 = 0;
920048 inode->sb_attached = NULL;
920049 inode->sb = 0;
920050 inode->ino = 0; // Must be zero. [*]
920051 inode->blkcnt = 0;
920052 inode->references = 1;
920053 inode->changed = 0;
920054 inode->pipe_dir = 1; // Must start with write.
920055 inode->pipe_off_read = 0;
920056 inode->pipe_off_write = 0;
920057 inode->pipe_ref_read = 0;
920058 inode->pipe_ref_write = 0;
920059 //
920060 // Add all access permissions.
920061 //
920062 inode->mode |= (S_IRWXU | S_IRWXG | S_IRWXO);
920063 //
920064 // Return the inode pointer.
920065 //
920066 return (inode);
920067 }
|
|
94.5.18
kernel/fs/inode_pipe_read.c
Si veda la sezione 93.6.17.
930001 #include <kernel/fs.h>
930002 #include <errno.h>
930003 //----------------------------------------------------------
930004 ssize_t
930005 inode_pipe_read (inode_t * inode, void *buffer,
930006 size_t count, int *eof)
930007 {
930008 unsigned char *buffer_s;
930009 unsigned char *buffer_d = buffer;
930010 int i;
930011 //
930012 // The inode pointer must be valid.
930013 //
930014 if (inode == NULL)
930015 {
930016 errset (EINVAL); // Invalid argument.
930017 return ((ssize_t) - 1);
930018 }
930019 //
930020 // Check the current pipe direction and see if can
930021 // be
930022 // read something.
930023 //
930024 if (inode->pipe_dir)
930025 {
930026 //
930027 // Write: if indexes are the same, cannot read
930028 // anything.
930029 //
930030 if (inode->pipe_off_write == inode->pipe_off_read)
930031 {
930032 //
930033 // Cannot read.
930034 //
930035 if (inode->pipe_ref_write == 0)
930036 {
930037 if (eof != NULL)
930038 {
930039 *eof = 1;
930040 }
930041 }
930042 return ((ssize_t) 0);
930043 }
930044 }
930045 else
930046 {
930047 //
930048 // Read: the pipe is waiting for a read.
930049 //
930050 ;
930051 }
930052 //
930053 // Might read something. Set the pointer to the
930054 // source buffer,
930055 // that is the area used for direct zones, including
930056 // first
930057 // indirect pointers (total: (7+2)*2 = 18 bytes).
930058 //
930059 buffer_s = (void *) &(inode->direct[0]);
930060 //
930061 i = 0;
930062 //
930063 if (inode->pipe_off_read >= inode->pipe_off_write)
930064 {
930065 for (; i < count; i++)
930066 {
930067 if (inode->pipe_off_read < INODE_PIPE_BUFFER_SIZE)
930068 {
930069 buffer_d[i] = buffer_s[inode->pipe_off_read];
930070 inode->pipe_off_read++;
930071 }
930072 else
930073 {
930074 inode->pipe_off_read = 0;
930075 break;
930076 }
930077 }
930078 }
930079 //
930080 if (inode->pipe_off_read < inode->pipe_off_write)
930081 {
930082 for (; i < count; i++)
930083 {
930084 if (inode->pipe_off_read < inode->pipe_off_write)
930085 {
930086 buffer_d[i] = buffer_s[inode->pipe_off_read];
930087 inode->pipe_off_read++;
930088 }
930089 else
930090 {
930091 break;
930092 }
930093 }
930094 }
930095 //
930096 // At this point, it is time to set the direction to
930097 // write;
930098 // it doesn't matter if the direction is already set
930099 // so.
930100 //
930101 if (inode->pipe_off_read == inode->pipe_off_write)
930102 {
930103 inode->pipe_dir = 1;
930104 }
930105 //
930106 // Ok.
930107 //
930108 return ((ssize_t) i);
930109 }
|
|
94.5.19
kernel/fs/inode_pipe_write.c
Si veda la sezione 93.6.18.
940001 #include <kernel/fs.h>
940002 #include <errno.h>
940003 //----------------------------------------------------------
940004 ssize_t
940005 inode_pipe_write (inode_t * inode, const void *buffer,
940006 size_t count)
940007 {
940008 const unsigned char *buffer_s = buffer;
940009 unsigned char *buffer_d;
940010 int i;
940011 //
940012 // The inode pointer must be valid.
940013 //
940014 if (inode == NULL)
940015 {
940016 errset (EINVAL); // Invalid argument.
940017 return ((ssize_t) - 1);
940018 }
940019 //
940020 // Check the current pipe direction and see if can
940021 // be
940022 // written something.
940023 //
940024 if (inode->pipe_dir)
940025 {
940026 //
940027 // Write: the pipe is waiting for a write.
940028 //
940029 ;
940030 }
940031 else
940032 {
940033 //
940034 // Read: if indexes are the same, cannot write
940035 // anything.
940036 //
940037 if (inode->pipe_off_write == inode->pipe_off_read)
940038 {
940039 //
940040 // Cannot write. More checks will be made by
940041 // `s_write()'.
940042 //
940043 return ((ssize_t) 0);
940044 }
940045 }
940046 //
940047 // Might write something. Set the pointer to the
940048 // destination buffer,
940049 // that is the area used for direct zones, including
940050 // first indirect
940051 // pointers (total: (7+2)*2 = 18 bytes).
940052 //
940053 buffer_d = (void *) &(inode->direct[0]);
940054 //
940055 i = 0;
940056 //
940057 if (inode->pipe_off_write >= inode->pipe_off_read)
940058 {
940059 for (; i < count; i++)
940060 {
940061 if (inode->pipe_off_write <
940062 INODE_PIPE_BUFFER_SIZE)
940063 {
940064 buffer_d[inode->pipe_off_write] = buffer_s[i];
940065 inode->pipe_off_write++;
940066 }
940067 else
940068 {
940069 inode->pipe_off_write = 0;
940070 break;
940071 }
940072 }
940073 }
940074 //
940075 if (inode->pipe_off_write < inode->pipe_off_read)
940076 {
940077 for (; i < count; i++)
940078 {
940079 if (inode->pipe_off_write < inode->pipe_off_read)
940080 {
940081 buffer_d[inode->pipe_off_write] = buffer_s[i];
940082 inode->pipe_off_write++;
940083 }
940084 else
940085 {
940086 break;
940087 }
940088 }
940089 }
940090 //
940091 // At this point, it is time to set the direction to
940092 // read;
940093 // it doesn't matter if the direction is already set
940094 // so.
940095 //
940096 if (inode->pipe_off_write == inode->pipe_off_read)
940097 {
940098 inode->pipe_dir = 0;
940099 }
940100 //
940101 // Ok.
940102 //
940103 return ((ssize_t) i);
940104 }
|
|
94.5.20
kernel/fs/inode_print.c
Si veda la sezione 93.6.19.
950001 #include <sys/os32.h>
950002 #include <kernel/fs.h>
950003 #include <kernel/lib_k.h>
950004 #include <time.h>
950005 //----------------------------------------------------------
950006 void
950007 inode_print (void)
950008 {
950009 int i;
950010 dev_t device_attached = 0;
950011 time_t time;
950012 struct tm *timeptr;
950013 char type;
950014 dev_t device;
950015 //
950016 k_printf
950017 (" dev ino ref c mntd t mode uid gid size Kib "
950018 "date time lnk dirct[0]\n");
950019 //
950020 for (i = 0; i < INODE_MAX_SLOTS; i++)
950021 {
950022 if (inode_table[i].references <= 0)
950023 {
950024 continue;
950025 }
950026 //
950027 // Calculate modification time.
950028 //
950029 time = inode_table[i].time;
950030 //
950031 timeptr = gmtime (&time);
950032 //
950033 // Get type from mode.
950034 //
950035 if (S_ISBLK (inode_table[i].mode))
950036 type = 'b';
950037 else if (S_ISCHR (inode_table[i].mode))
950038 type = 'c';
950039 else if (S_ISFIFO (inode_table[i].mode))
950040 type = 'p';
950041 else if (S_ISREG (inode_table[i].mode))
950042 type = '-';
950043 else if (S_ISDIR (inode_table[i].mode))
950044 type = 'd';
950045 else if (S_ISLNK (inode_table[i].mode))
950046 type = 'l';
950047 else if (S_ISSOCK (inode_table[i].mode))
950048 type = 's';
950049 else
950050 type = '?';
950051 //
950052 // Is it a mount point?
950053 //
950054 if (inode_table[i].sb_attached != NULL)
950055 {
950056 device_attached =
950057 inode_table[i].sb_attached->device;
950058 }
950059 //
950060 // Is there a super block device?
950061 //
950062 if (inode_table[i].sb == NULL)
950063 {
950064 device = 0;
950065 }
950066 else
950067 {
950068 device = inode_table[i].sb->device;
950069 }
950070 //
950071 // Print data.
950072 //
950073 k_printf
950074 ("%04x %5i %3i %c %04x %c %04o %4i %3i %8i "
950075 "%4i.%02i.%02i %2i:%02i:%02i %3i %08x\n",
950076 (unsigned int) device,
950077 (unsigned int) inode_table[i].ino,
950078 (unsigned int) inode_table[i].references,
950079 (inode_table[i].changed ? '!' : ' '),
950080 (unsigned int) device_attached, type,
950081 (unsigned int) inode_table[i].mode,
950082 (unsigned int) inode_table[i].uid,
950083 (unsigned int) inode_table[i].gid,
950084 (unsigned int) (inode_table[i].size / 1024),
950085 timeptr->tm_year, timeptr->tm_mon,
950086 timeptr->tm_mday, timeptr->tm_hour,
950087 timeptr->tm_min, timeptr->tm_sec,
950088 (unsigned int) inode_table[i].links,
950089 (unsigned int) inode_table[i].direct[0]);
950090 }
950091 }
|
|
94.5.21
kernel/fs/inode_put.c
Si veda la sezione 93.6.20.
960001 #include <kernel/fs.h>
960002 #include <errno.h>
960003 #include <kernel/lib_k.h>
960004 //----------------------------------------------------------
960005 int
960006 inode_put (inode_t * inode)
960007 {
960008 int status;
960009 //
960010 // Check for valid argument.
960011 //
960012 if (inode == NULL)
960013 {
960014 errset (EINVAL); // Invalid argument.
960015 return (-1);
960016 }
960017 //
960018 // Check for valid references.
960019 //
960020 if (inode->references <= 0)
960021 {
960022 errset (EUNKNOWN); // Cannot put an inode with
960023 return (-1); // zero or negative
960024 // references.
960025 }
960026 //
960027 // Debug.
960028 //
960029 if (inode->ino != 0 && inode->sb->device == 0)
960030 {
960031 k_printf
960032 ("kernel alert: trying to close "
960033 "inode with device "
960034 "zero, but a number different than zero!\n");
960035 errset (EUNKNOWN); // Cannot put an inode
960036 // with
960037 return (-1); // zero or negative
960038 // references.
960039 }
960040 //
960041 // There is at least one reference: now the
960042 // references value is
960043 // reduced.
960044 //
960045 inode->references--;
960046 inode->changed = 1;
960047 //
960048 // If `inode->ino' is zero, it means that the inode
960049 // was created in memory, but there is no file system
960050 // for it. For example, it might be a standard I/O
960051 // inode create automatically for a process.
960052 // Inodes with number zero cannot be removed from a
960053 // file system.
960054 //
960055 if (inode->ino == 0)
960056 {
960057 //
960058 // Nothing to do: just return.
960059 //
960060 return (0);
960061 }
960062 //
960063 // References counter might be zero.
960064 //
960065 if (inode->references == 0)
960066 {
960067 //
960068 // Check if the inode is to be deleted (until
960069 // there are
960070 // run time references, the inode cannot be
960071 // removed).
960072 //
960073 if (inode->links == 0
960074 || (S_ISDIR (inode->mode) && inode->links == 1))
960075 {
960076 //
960077 // The inode has no more run time references
960078 // and file system
960079 // links are also zero (or one for a
960080 // directory): remove it!
960081 //
960082 status = inode_truncate (inode);
960083 if (status != 0)
960084 {
960085 k_perror (NULL);
960086 }
960087 //
960088 inode_free (inode);
960089 return (0);
960090 }
960091 }
960092 //
960093 // Save inode to disk and return.
960094 //
960095 return (inode_save (inode));
960096 }
|
|
94.5.22
kernel/fs/inode_reference.c
Si veda la sezione 93.6.21.
970001 #include <kernel/fs.h>
970002 #include <errno.h>
970003 //----------------------------------------------------------
970004 inode_t *
970005 inode_reference (dev_t device, ino_t ino)
970006 {
970007 int s; // Slot index.
970008 sb_t *sb_table = sb_reference (0);
970009 //
970010 // If device is zero, and inode is zero, a reference
970011 // to the whole
970012 // table is returned.
970013 //
970014 if (device == 0 && ino == 0)
970015 {
970016 return (inode_table);
970017 }
970018 //
970019 // If device is ((dev_t) -1) and the inode is
970020 // ((ino_t) -1), a
970021 // reference to a free inode slot is returned.
970022 //
970023 if (device == (dev_t) - 1 && ino == ((ino_t) - 1))
970024 {
970025 for (s = 0; s < INODE_MAX_SLOTS; s++)
970026 {
970027 if (inode_table[s].references == 0)
970028 {
970029 return (&inode_table[s]);
970030 }
970031 }
970032 return (NULL);
970033 }
970034 //
970035 // If device is zero and the inode is 1, a reference
970036 // to the root
970037 // directory inode is returned.
970038 //
970039 if (device == 0 && ino == 1)
970040 {
970041 //
970042 // The super block table is to be scanned.
970043 //
970044 for (device = 0, s = 0; s < SB_MAX_SLOTS; s++)
970045 {
970046 if (sb_table[s].device != 0
970047 && (sb_table[s].inode_mounted_on->
970048 sb_attached->device ==
970049 sb_table[s].device))
970050 {
970051 device = sb_table[s].device;
970052 break;
970053 }
970054 }
970055 if (device == 0)
970056 {
970057 errset (E_CANNOT_FIND_ROOT_DEVICE);
970058 return (NULL);
970059 }
970060 //
970061 // Scan the inode table to find inode 1 and the
970062 // same device.
970063 //
970064 for (s = 0; s < INODE_MAX_SLOTS; s++)
970065 {
970066 if (inode_table[s].sb->device == device &&
970067 inode_table[s].ino == 1)
970068 {
970069 return (&inode_table[s]);
970070 }
970071 }
970072 //
970073 // Cannot find a root file system inode.
970074 //
970075 errset (E_CANNOT_FIND_ROOT_INODE);
970076 return (NULL);
970077 }
970078 //
970079 // A device and an inode number were selected: find
970080 // the inode
970081 // associated to it.
970082 //
970083 for (s = 0; s < INODE_MAX_SLOTS; s++)
970084 {
970085 if (inode_table[s].sb->device == device &&
970086 inode_table[s].ino == ino)
970087 {
970088 return (&inode_table[s]);
970089 }
970090 }
970091 //
970092 // The inode was not found.
970093 //
970094 return (NULL);
970095 }
|
|
94.5.23
kernel/fs/inode_save.c
Si veda la sezione 93.6.22.
980001 #include <kernel/fs.h>
980002 #include <errno.h>
980003 #include <kernel/dev.h>
980004 //----------------------------------------------------------
980005 int
980006 inode_save (inode_t * inode)
980007 {
980008 size_t size;
980009 unsigned long int start;
980010 ssize_t n;
980011 //
980012 // Check for valid argument.
980013 //
980014 if (inode == NULL)
980015 {
980016 errset (EINVAL); // Invalid argument.
980017 return (-1);
980018 }
980019 //
980020 // If the inode number is zero, no file system is
980021 // involved!
980022 //
980023 if (inode->ino == 0)
980024 {
980025 return (0);
980026 }
980027 //
980028 // Save the super block to disk.
980029 //
980030 sb_save (inode->sb);
980031 //
980032 // Save the inode to disk.
980033 //
980034 if (inode->changed)
980035 {
980036 size = offsetof (inode_t, sb);
980037 //
980038 // Calculating start position for write.
980039 //
980040 //
980041 // Boot block: 1024 bytes
980042 //
980043 start = 1024;
980044 //
980045 // Super block: + 1024 bytes
980046 //
980047 start += 1024;
980048 //
980049 // Inode bit map:
980050 //
980051 start += (inode->sb->map_inode_blocks * 1024);
980052 //
980053 // Zone bit map:
980054 //
980055 start += (inode->sb->map_zone_blocks * 1024);
980056 //
980057 // Previous inodes: consider that the inode zero
980058 // is present in the inode map, but not in the
980059 // inode table.
980060 //
980061 start += ((inode->ino - 1) * size);
980062 //
980063 // Write the inode.
980064 //
980065 n =
980066 dev_io ((pid_t) - 1, inode->sb->device,
980067 DEV_WRITE, start, inode, size, NULL);
980068 //
980069 inode->changed = 0;
980070 }
980071 return (0);
980072 }
|
|
94.5.24
kernel/fs/inode_stdio_dev_make.c
Si veda la sezione 93.6.23.
990001 #include <kernel/fs.h>
990002 #include <errno.h>
990003 #include <kernel/lib_k.h>
990004 #include <kernel/lib_s.h>
990005 //----------------------------------------------------------
990006 inode_t *
990007 inode_stdio_dev_make (dev_t device, mode_t mode)
990008 {
990009 inode_t *inode;
990010 //
990011 // Check for arguments.
990012 //
990013 if (mode == 0 || device == 0)
990014 {
990015 errset (EINVAL); // Invalid argument.
990016 return (NULL);
990017 }
990018 //
990019 // Find a free inode.
990020 //
990021 inode = inode_reference ((dev_t) - 1, (ino_t) - 1);
990022 if (inode == NULL)
990023 {
990024 //
990025 // No free slot available.
990026 //
990027 errset (ENFILE); // Too many files open in
990028 // system.
990029 return (NULL);
990030 }
990031 //
990032 // Put data inside the inode. Please note that
990033 // `inode->ino' must be
990034 // zero, because it is necessary to recognize it as
990035 // an internal
990036 // inode with no file system. Otherwise, with a
990037 // value different than
990038 // zero, `inode_put()' will try to remove it. [*]
990039 //
990040 inode->mode = mode;
990041 inode->uid = 0;
990042 inode->gid = 0;
990043 inode->size = 0;
990044 inode->time = s_time ((pid_t) 0, NULL);
990045 inode->links = 0;
990046 inode->direct[0] = device;
990047 inode->direct[1] = 0;
990048 inode->direct[2] = 0;
990049 inode->direct[3] = 0;
990050 inode->direct[4] = 0;
990051 inode->direct[5] = 0;
990052 inode->direct[6] = 0;
990053 inode->indirect1 = 0;
990054 inode->indirect2 = 0;
990055 inode->sb_attached = NULL;
990056 inode->sb = 0;
990057 inode->ino = 0; // Must be zero. [*]
990058 inode->blkcnt = 0;
990059 inode->references = 1;
990060 inode->changed = 0;
990061 //
990062 // Add all access permissions.
990063 //
990064 inode->mode |= (S_IRWXU | S_IRWXG | S_IRWXO);
990065 //
990066 // Return the inode pointer.
990067 //
990068 return (inode);
990069 }
|
|
94.5.25
kernel/fs/inode_truncate.c
Si veda la sezione 93.6.24.
1000001 #include <kernel/fs.h>
1000002 #include <errno.h>
1000003 #include <kernel/lib_k.h>
1000004 //----------------------------------------------------------
1000005 int
1000006 inode_truncate (inode_t * inode)
1000007 {
1000008 unsigned int indirect_zones;
1000009 zno_t zone_table1[INODE_MAX_INDIRECT_ZONES];
1000010 zno_t zone_table2[INODE_MAX_INDIRECT_ZONES];
1000011 unsigned int i; // Direct index.
1000012 unsigned int i0; // Single indirect index.
1000013 unsigned int i1; // Double indirect first
1000014 // index.
1000015 unsigned int i2; // Double indirect second
1000016 // index.
1000017 int status; // `zone_read()' return value.
1000018 //
1000019 // Check argument.
1000020 //
1000021 if (inode == NULL)
1000022 {
1000023 errset (EINVAL);
1000024 return (-1);
1000025 }
1000026 //
1000027 // Calculate how many indirect zone numbers are
1000028 // stored inside
1000029 // a zone: it depends on the zone size.
1000030 //
1000031 indirect_zones = inode->sb->blksize / 2;
1000032 //
1000033 // Scan and release direct zones. Errors are
1000034 // ignored.
1000035 //
1000036 for (i = 0; i < 7; i++)
1000037 {
1000038 zone_free (inode->sb, inode->direct[i]);
1000039 inode->direct[i] = 0;
1000040 }
1000041 //
1000042 // Scan single indirect zones, if present.
1000043 //
1000044 if (inode->blkcnt > 7 && inode->indirect1 != 0)
1000045 {
1000046 //
1000047 // There is a single indirect table to load.
1000048 // Errors are
1000049 // almost ignored.
1000050 //
1000051 status =
1000052 zone_read (inode->sb, inode->indirect1,
1000053 zone_table1);
1000054 if (status == 0)
1000055 {
1000056 //
1000057 // Scan the table and remove zones.
1000058 //
1000059 for (i0 = 0; i0 < indirect_zones; i0++)
1000060 {
1000061 zone_free (inode->sb, zone_table1[i0]);
1000062 }
1000063 }
1000064 //
1000065 // Remove indirect table too.
1000066 //
1000067 zone_free (inode->sb, inode->indirect1);
1000068 //
1000069 // Clear single indirect reference inside the
1000070 // inode.
1000071 //
1000072 inode->indirect1 = 0;
1000073 }
1000074 //
1000075 // Scan double indirect zones, if present.
1000076 //
1000077 if (inode->blkcnt > (7 + indirect_zones)
1000078 && inode->indirect2 != 0)
1000079 {
1000080 //
1000081 // There is a double indirect table to load.
1000082 // Errors are
1000083 // almost ignored.
1000084 //
1000085 status =
1000086 zone_read (inode->sb, inode->indirect2,
1000087 zone_table1);
1000088 if (status == 0)
1000089 {
1000090 //
1000091 // Scan the table and get second level
1000092 // indirection.
1000093 //
1000094 for (i1 = 0; i1 < indirect_zones; i1++)
1000095 {
1000096 if ((inode->blkcnt
1000097 >
1000098 (7 + indirect_zones +
1000099 indirect_zones * i1))
1000100 && zone_table1[i1] != 0)
1000101 {
1000102 //
1000103 // There is a second level table to
1000104 // load.
1000105 //
1000106 status =
1000107 zone_read (inode->sb,
1000108 zone_table1[i1],
1000109 zone_table2);
1000110 if (status == 0)
1000111 {
1000112 //
1000113 // Release zones.
1000114 //
1000115 for (i2 = 0;
1000116 i2 < indirect_zones &&
1000117 (inode->blkcnt >
1000118 (7 + indirect_zones +
1000119 indirect_zones * i1 +
1000120 i2)); i2++)
1000121 {
1000122 zone_free (inode->sb,
1000123 zone_table2[i2]);
1000124 }
1000125 //
1000126 // Remove second level indirect
1000127 // table.
1000128 //
1000129 zone_free (inode->sb,
1000130 zone_table1[i1]);
1000131 }
1000132 }
1000133 }
1000134 //
1000135 // Remove first level indirect table.
1000136 //
1000137 zone_free (inode->sb, inode->indirect2);
1000138 }
1000139 //
1000140 // Clear single indirect reference inside the
1000141 // inode.
1000142 //
1000143 inode->indirect2 = 0;
1000144 }
1000145 //
1000146 // Update super block and inode data.
1000147 //
1000148 sb_save (inode->sb);
1000149 inode->size = 0;
1000150 inode->changed = 1;
1000151 inode_save (inode);
1000152 //
1000153 // Successful return.
1000154 //
1000155 return (0);
1000156 }
|
|
94.5.26
kernel/fs/inode_zone.c
Si veda la sezione 93.6.25.
1010001 #include <kernel/fs.h>
1010002 #include <errno.h>
1010003 #include <kernel/lib_k.h>
1010004 //----------------------------------------------------------
1010005 zno_t
1010006 inode_zone (inode_t * inode, zno_t fzone, int write)
1010007 {
1010008 unsigned int indirect_zones;
1010009 unsigned int allocated_zone;
1010010 zno_t zone_table[INODE_MAX_INDIRECT_ZONES];
1010011 char buffer[SB_MAX_ZONE_SIZE];
1010012 unsigned int i0; // Single indirect index.
1010013 unsigned int i1; // Double indirect first
1010014 // index.
1010015 unsigned int i2; // Double indirect second
1010016 // index.
1010017 int status;
1010018 zno_t zone_second; // Second level table zone.
1010019 //
1010020 // Check to have a valid inode.
1010021 //
1010022 if (inode == NULL)
1010023 {
1010024 errset (EINVAL);
1010025 return ((zno_t) - 1);
1010026 }
1010027 //
1010028 // Calculate how many indirect zone numbers are
1010029 // stored inside
1010030 // a zone: it depends on the zone size.
1010031 //
1010032 indirect_zones = inode->sb->blksize / 2;
1010033 //
1010034 // Convert file-zone number into a zone number.
1010035 //
1010036 if (fzone < 7)
1010037 {
1010038 //
1010039 // 0 <= fzone <= 6
1010040 // The zone number is inside the direct zone
1010041 // references.
1010042 // Verify to have such zone.
1010043 //
1010044 if (inode->direct[fzone] == 0)
1010045 {
1010046 //
1010047 // There is not such zone, but we do not
1010048 // consider
1010049 // it an error, because a file can be not
1010050 // contiguous.
1010051 //
1010052 if (!write)
1010053 {
1010054 return ((zno_t) 0);
1010055 }
1010056 //
1010057 // Must be allocated.
1010058 //
1010059 allocated_zone = zone_alloc (inode->sb);
1010060 if (allocated_zone == 0)
1010061 {
1010062 //
1010063 // Cannot allocate the zone. The
1010064 // variable `errno' is
1010065 // set by `zone_alloc()'.
1010066 //
1010067 return ((zno_t) - 1);
1010068 }
1010069 //
1010070 // The zone is allocated: clear the zone and
1010071 // save.
1010072 //
1010073 memset (buffer, 0, SB_MAX_ZONE_SIZE);
1010074 status =
1010075 zone_write (inode->sb, allocated_zone, buffer);
1010076 if (status < 0)
1010077 {
1010078 //
1010079 // Cannot overwrite the zone. The
1010080 // variable `errno' is
1010081 // set by `zone_write()'.
1010082 //
1010083 return ((zno_t) - 1);
1010084 }
1010085 //
1010086 // The zone is allocated and cleared: save
1010087 // the inode.
1010088 //
1010089 inode->direct[fzone] = allocated_zone;
1010090 inode->changed = 1;
1010091 status = inode_save (inode);
1010092 if (status != 0)
1010093 {
1010094 //
1010095 // Cannot save the inode. The variable
1010096 // `errno' is
1010097 // set `inode_save()'.
1010098 //
1010099 return ((zno_t) - 1);
1010100 }
1010101 }
1010102 //
1010103 // The zone is there: return it.
1010104 //
1010105 return (inode->direct[fzone]);
1010106 }
1010107 if (fzone < 7 + indirect_zones)
1010108 {
1010109 //
1010110 // 7 <= fzone <= (6 + indirect_zones)
1010111 // The zone number is inside the single indirect
1010112 // zone
1010113 // references: verify to have the indirect zone
1010114 // table.
1010115 //
1010116 if (inode->indirect1 == 0)
1010117 {
1010118 //
1010119 // There is not such zone, but it is not an
1010120 // error.
1010121 //
1010122 if (!write)
1010123 {
1010124 return ((zno_t) 0);
1010125 }
1010126 //
1010127 // The first level of indirection must be
1010128 // initialized.
1010129 //
1010130 allocated_zone = zone_alloc (inode->sb);
1010131 if (allocated_zone == 0)
1010132 {
1010133 //
1010134 // Cannot allocate the zone for the
1010135 // indirection table:
1010136 // this is an error and the `errno'
1010137 // value is produced
1010138 // by `zone_alloc()'.
1010139 //
1010140 return ((zno_t) - 1);
1010141 }
1010142 //
1010143 // The zone for the indirection table is
1010144 // allocated:
1010145 // clear the zone and save.
1010146 //
1010147 memset (buffer, 0, SB_MAX_ZONE_SIZE);
1010148 status =
1010149 zone_write (inode->sb, allocated_zone, buffer);
1010150 if (status < 0)
1010151 {
1010152 //
1010153 // Cannot overwrite the zone. The
1010154 // variable `errno' is
1010155 // set by `zone_write()'.
1010156 //
1010157 return ((zno_t) - 1);
1010158 }
1010159 //
1010160 // The indirection table zone is allocated
1010161 // and cleared:
1010162 // save the inode.
1010163 //
1010164 inode->indirect1 = allocated_zone;
1010165 inode->changed = 1;
1010166 status = inode_save (inode);
1010167 if (status != 0)
1010168 {
1010169 //
1010170 // Cannot save the inode. This is an
1010171 // error and the value
1010172 // for `errno' is produced by
1010173 // `inode_save()'.
1010174 //
1010175 return ((zno_t) - 1);
1010176 }
1010177 }
1010178 //
1010179 // An indirect table is present inside the file
1010180 // system:
1010181 // load it.
1010182 //
1010183 status =
1010184 zone_read (inode->sb, inode->indirect1, zone_table);
1010185 if (status != 0)
1010186 {
1010187 //
1010188 // Cannot load the indirect table. This is
1010189 // an error and the
1010190 // value for `errno' is assigned by function
1010191 // `zone_read()'.
1010192 //
1010193 return ((zno_t) - 1);
1010194 }
1010195 //
1010196 // The indirect table was read. Calculate the
1010197 // index inside
1010198 // the table, for the requested zone.
1010199 //
1010200 i0 = (fzone - 7);
1010201 //
1010202 // Check if the zone is to be allocated.
1010203 //
1010204 if (zone_table[i0] == 0)
1010205 {
1010206 //
1010207 // There is not such zone, but it is not an
1010208 // error.
1010209 //
1010210 if (!write)
1010211 {
1010212 return ((zno_t) 0);
1010213 }
1010214 //
1010215 // The zone must be allocated.
1010216 //
1010217 allocated_zone = zone_alloc (inode->sb);
1010218 if (allocated_zone == 0)
1010219 {
1010220 //
1010221 // There is no space for the zone
1010222 // allocation. The
1010223 // variable `errno' is already updated
1010224 // by
1010225 // `zone_alloc()'.
1010226 //
1010227 return ((zno_t) - 1);
1010228 }
1010229 //
1010230 // The zone is allocated: clear the zone and
1010231 // save.
1010232 //
1010233 memset (buffer, 0, SB_MAX_ZONE_SIZE);
1010234 status =
1010235 zone_write (inode->sb, allocated_zone, buffer);
1010236 if (status < 0)
1010237 {
1010238 //
1010239 // Cannot overwrite the zone. The
1010240 // variable `errno' is
1010241 // set by `zone_write()'.
1010242 //
1010243 return ((zno_t) - 1);
1010244 }
1010245 //
1010246 // The zone is allocated and cleared: update
1010247 // the indirect
1010248 // zone table an save it. The inode is not
1010249 // modified,
1010250 // because the indirect table is outside.
1010251 //
1010252 zone_table[i0] = allocated_zone;
1010253 status =
1010254 zone_write (inode->sb, inode->indirect1,
1010255 zone_table);
1010256 if (status != 0)
1010257 {
1010258 //
1010259 // Cannot save the zone. The variable
1010260 // `errno' is already
1010261 // set by `zone_write()'.
1010262 //
1010263 return ((zno_t) - 1);
1010264 }
1010265 }
1010266 //
1010267 // The zone is allocated.
1010268 //
1010269 return (zone_table[i0]);
1010270 }
1010271 else
1010272 {
1010273 //
1010274 // (7 + indirect_zones) <= fzone
1010275 // The zone number is inside the double indirect
1010276 // zone
1010277 // references.
1010278 // Verify to have the first level of second
1010279 // indirection.
1010280 //
1010281 if (inode->indirect2 == 0)
1010282 {
1010283 //
1010284 // There is not such zone, but it is not an
1010285 // error.
1010286 //
1010287 if (!write)
1010288 {
1010289 return ((zno_t) 0);
1010290 }
1010291 //
1010292 // The first level of second indirection
1010293 // must be
1010294 // initialized.
1010295 //
1010296 allocated_zone = zone_alloc (inode->sb);
1010297 if (allocated_zone == 0)
1010298 {
1010299 //
1010300 // Cannot allocate the zone. The
1010301 // variable `errno' is
1010302 // set by `zone_alloc()'.
1010303 //
1010304 return ((zno_t) - 1);
1010305 }
1010306 //
1010307 // The zone for the indirection table is
1010308 // allocated:
1010309 // clear the zone and save.
1010310 //
1010311 memset (buffer, 0, SB_MAX_ZONE_SIZE);
1010312 status =
1010313 zone_write (inode->sb, allocated_zone, buffer);
1010314 if (status < 0)
1010315 {
1010316 //
1010317 // Cannot overwrite the zone. The
1010318 // variable `errno' is
1010319 // set by `zone_write()'.
1010320 //
1010321 return ((zno_t) - 1);
1010322 }
1010323 //
1010324 // The zone for the indirection table is
1010325 // allocated and
1010326 // cleared: save the inode.
1010327 //
1010328 inode->indirect2 = allocated_zone;
1010329 inode->changed = 1;
1010330 status = inode_save (inode);
1010331 if (status != 0)
1010332 {
1010333 //
1010334 // Cannot save the inode. The variable
1010335 // `errno' is
1010336 // set by `inode_save()'.
1010337 //
1010338 return ((zno_t) - 1);
1010339 }
1010340 }
1010341 //
1010342 // The first level of second indirection is
1010343 // present:
1010344 // Read the second indirect table.
1010345 //
1010346 status =
1010347 zone_read (inode->sb, inode->indirect2, zone_table);
1010348 if (status != 0)
1010349 {
1010350 //
1010351 // Cannot read the second indirect table.
1010352 // The variable
1010353 // `errno' is set by `zone_read()'.
1010354 //
1010355 return ((zno_t) - 1);
1010356 }
1010357 //
1010358 // The first double indirect table was read:
1010359 // calculate
1010360 // indexes inside first and second level of
1010361 // table.
1010362 //
1010363 fzone -= 7;
1010364 fzone -= indirect_zones;
1010365 i1 = fzone / indirect_zones;
1010366 i2 = fzone % indirect_zones;
1010367 //
1010368 // Verify to have a second level.
1010369 //
1010370 if (zone_table[i1] == 0)
1010371 {
1010372 //
1010373 // There is not such zone, but it is not an
1010374 // error.
1010375 //
1010376 if (!write)
1010377 {
1010378 return ((zno_t) 0);
1010379 }
1010380 //
1010381 // The second level must be initialized.
1010382 //
1010383 allocated_zone = zone_alloc (inode->sb);
1010384 if (allocated_zone == 0)
1010385 {
1010386 //
1010387 // Cannot allocate the zone. The
1010388 // variable `errno' is set
1010389 // by `zone_alloc()'.
1010390 //
1010391 return ((zno_t) - 1);
1010392 }
1010393 //
1010394 // The zone for the indirection table is
1010395 // allocated:
1010396 // clear the zone and save.
1010397 //
1010398 memset (buffer, 0, SB_MAX_ZONE_SIZE);
1010399 status =
1010400 zone_write (inode->sb, allocated_zone, buffer);
1010401 if (status < 0)
1010402 {
1010403 //
1010404 // Cannot overwrite the zone. The
1010405 // variable `errno' is
1010406 // set by `zone_write()'.
1010407 //
1010408 return ((zno_t) - 1);
1010409 }
1010410 //
1010411 // Update the first level index and save it.
1010412 //
1010413 zone_table[i1] = allocated_zone;
1010414 status =
1010415 zone_write (inode->sb, inode->indirect2,
1010416 zone_table);
1010417 if (status != 0)
1010418 {
1010419 //
1010420 // Cannot write the zone. The variable
1010421 // `errno' is set
1010422 // by `zone_write()'.
1010423 //
1010424 return ((zno_t) - 1);
1010425 }
1010426 }
1010427 //
1010428 // The second level can be read, overwriting the
1010429 // array
1010430 // `zone_table[]'. The zone number for the
1010431 // second level
1010432 // indirection table is saved inside
1010433 // `zone_second', before
1010434 // overwriting the array.
1010435 //
1010436 zone_second = zone_table[i1];
1010437 status =
1010438 zone_read (inode->sb, zone_second, zone_table);
1010439 if (status != 0)
1010440 {
1010441 //
1010442 // Cannot read the second level indirect
1010443 // table. The variable
1010444 // `errno' is set by `zone_read()'.
1010445 //
1010446 return ((zno_t) - 1);
1010447 }
1010448 //
1010449 // The second level was read and `zone_table[]'
1010450 // is now
1010451 // such second one: check if the zone is to be
1010452 // allocated.
1010453 //
1010454 if (zone_table[i2] == 0)
1010455 {
1010456 //
1010457 // There is not such zone, but it is not an
1010458 // error.
1010459 //
1010460 if (!write)
1010461 {
1010462 return ((zno_t) 0);
1010463 }
1010464 //
1010465 // Must be allocated.
1010466 //
1010467 allocated_zone = zone_alloc (inode->sb);
1010468 if (allocated_zone == 0)
1010469 {
1010470 //
1010471 // Cannot allocate the zone. The
1010472 // variable `errno' is set
1010473 // by `zone_alloc()'.
1010474 //
1010475 return ((zno_t) - 1);
1010476 }
1010477 //
1010478 // The zone is allocated: clear the zone and
1010479 // save.
1010480 //
1010481 memset (buffer, 0, SB_MAX_ZONE_SIZE);
1010482 status =
1010483 zone_write (inode->sb, allocated_zone, buffer);
1010484 if (status < 0)
1010485 {
1010486 //
1010487 // Cannot overwrite the zone. The
1010488 // variable `errno' is
1010489 // set by `zone_write()'.
1010490 //
1010491 return ((zno_t) - 1);
1010492 }
1010493 //
1010494 // The zone was allocated and cleared:
1010495 // update the indirect
1010496 // zone table an save it. The inode is not
1010497 // modified, because
1010498 // the indirect table is outside.
1010499 //
1010500 zone_table[i2] = allocated_zone;
1010501 status =
1010502 zone_write (inode->sb, zone_second, zone_table);
1010503 if (status != 0)
1010504 {
1010505 //
1010506 // Cannot write the zone. The variable
1010507 // `errno' is set
1010508 // by `zone_write()'.
1010509 //
1010510 return ((zno_t) - 1);
1010511 }
1010512 }
1010513 //
1010514 // The zone is there: return the zone number.
1010515 //
1010516 return (zone_table[i2]);
1010517 }
1010518 }
|
|
94.5.27
kernel/fs/path_device.c
Si veda la sezione 93.6.38.
1020001 #include <kernel/fs.h>
1020002 #include <errno.h>
1020003 #include <kernel/proc.h>
1020004 //----------------------------------------------------------
1020005 dev_t
1020006 path_device (pid_t pid, const char *path)
1020007 {
1020008 proc_t *ps;
1020009 inode_t *inode;
1020010 dev_t device;
1020011 //
1020012 // Get process.
1020013 //
1020014 ps = proc_reference (pid);
1020015 //
1020016 inode = path_inode (pid, path);
1020017 if (inode == NULL)
1020018 {
1020019 errset (errno);
1020020 return ((dev_t) - 1);
1020021 }
1020022 //
1020023 if (!(S_ISBLK (inode->mode) || S_ISCHR (inode->mode)))
1020024 {
1020025 errset (ENODEV); // No such device.
1020026 inode_put (inode);
1020027 return ((dev_t) - 1);
1020028 }
1020029 //
1020030 device = inode->direct[0];
1020031 inode_put (inode);
1020032 return (device);
1020033 }
|
|
94.5.28
kernel/fs/path_fix.c
Si veda la sezione 93.6.39.
1030001 #include <kernel/fs.h>
1030002 #include <errno.h>
1030003 #include <kernel/proc.h>
1030004 //----------------------------------------------------------
1030005 int
1030006 path_fix (char *path)
1030007 {
1030008 char new_path[PATH_MAX];
1030009 char *token[PATH_MAX / 4];
1030010 int t; // Token index.
1030011 int token_size; // Token array effective size.
1030012 int comp; // String compare return value.
1030013 size_t path_size; // Path string size.
1030014 //
1030015 // Initialize token search.
1030016 //
1030017 token[0] = strtok (path, "/");
1030018 //
1030019 // Scan tokens.
1030020 //
1030021 for (t = 0;
1030022 t < PATH_MAX / 4 && token[t] != NULL;
1030023 t++, token[t] = strtok (NULL, "/"))
1030024 {
1030025 //
1030026 // If current token is `.', just ignore it.
1030027 //
1030028 comp = strcmp (token[t], ".");
1030029 if (comp == 0)
1030030 {
1030031 t--;
1030032 }
1030033 //
1030034 // If current token is `..', remove previous
1030035 // token,
1030036 // if there is one.
1030037 //
1030038 comp = strcmp (token[t], "..");
1030039 if (comp == 0)
1030040 {
1030041 if (t > 0)
1030042 {
1030043 t -= 2;
1030044 }
1030045 else
1030046 {
1030047 t = -1;
1030048 }
1030049 }
1030050 //
1030051 // `t' will be incremented and another token
1030052 // will be
1030053 // found.
1030054 //
1030055 }
1030056 //
1030057 // Save the token array effective size.
1030058 //
1030059 token_size = t;
1030060 //
1030061 // Initialize the new path string.
1030062 //
1030063 new_path[0] = '\0';
1030064 //
1030065 // Build the new path string.
1030066 //
1030067 if (token_size > 0)
1030068 {
1030069 for (t = 0; t < token_size; t++)
1030070 {
1030071 path_size = strlen (new_path);
1030072 strncat (new_path, "/", 2);
1030073 strncat (new_path, token[t],
1030074 PATH_MAX - path_size - 1);
1030075 }
1030076 }
1030077 else
1030078 {
1030079 strncat (new_path, "/", 2);
1030080 }
1030081 //
1030082 // Copy the new path into the original string.
1030083 //
1030084 strncpy (path, new_path, PATH_MAX);
1030085 //
1030086 // Return.
1030087 //
1030088 return (0);
1030089 }
|
|
94.5.29
kernel/fs/path_full.c
Si veda la sezione 93.6.40.
1040001 #include <kernel/fs.h>
1040002 #include <errno.h>
1040003 #include <kernel/proc.h>
1040004 //----------------------------------------------------------
1040005 int
1040006 path_full (const char *path, const char *path_cwd,
1040007 char *full_path)
1040008 {
1040009 unsigned int path_size;
1040010 //
1040011 // Check some arguments.
1040012 //
1040013 if (path == NULL || strlen (path) == 0
1040014 || full_path == NULL)
1040015 {
1040016 errset (EINVAL); // Invalid argument.
1040017 return (-1);
1040018 }
1040019 //
1040020 // The main path and the receiving one are right.
1040021 // Now arrange to get a full path name.
1040022 //
1040023 if (path[0] == '/')
1040024 {
1040025 strncpy (full_path, path, PATH_MAX);
1040026 full_path[PATH_MAX - 1] = 0;
1040027 }
1040028 else
1040029 {
1040030 if (path_cwd == NULL || strlen (path_cwd) == 0)
1040031 {
1040032 errset (EINVAL); // Invalid argument.
1040033 return (-1);
1040034 }
1040035 strncpy (full_path, path_cwd, PATH_MAX);
1040036 path_size = strlen (full_path);
1040037 strncat (full_path, "/", (PATH_MAX - path_size));
1040038 path_size = strlen (full_path);
1040039 strncat (full_path, path, (PATH_MAX - path_size));
1040040 }
1040041 //
1040042 // Fix path name so that it has no `..', `.', and no
1040043 // multiple `/'.
1040044 //
1040045 path_fix (full_path);
1040046 //
1040047 // Return.
1040048 //
1040049 return (0);
1040050 }
|
|
94.5.30
kernel/fs/path_inode.c
Si veda la sezione 93.6.41.
1050001 #include <kernel/fs.h>
1050002 #include <errno.h>
1050003 #include <kernel/proc.h>
1050004 #include <kernel/lib_k.h>
1050005 //----------------------------------------------------------
1050006 #define DIRECTORY_BUFFER_SIZE (SB_MAX_ZONE_SIZE/16)
1050007 //----------------------------------------------------------
1050008 inode_t *
1050009 path_inode (pid_t pid, const char *path)
1050010 {
1050011 proc_t *ps;
1050012 inode_t *inode;
1050013 dev_t device;
1050014 char full_path[PATH_MAX];
1050015 char *name;
1050016 char *next;
1050017 directory_t dir[DIRECTORY_BUFFER_SIZE];
1050018 char dir_name[NAME_MAX + 1];
1050019 off_t offset_dir;
1050020 ssize_t size_read;
1050021 size_t dir_size_read;
1050022 ssize_t size_to_read;
1050023 int comp;
1050024 int d; // Directory index;
1050025 int status; // inode_check() return status.
1050026 //
1050027 // Get process.
1050028 //
1050029 ps = proc_reference (pid);
1050030 //
1050031 // Arrange to get a packed full path name.
1050032 //
1050033 path_full (path, ps->path_cwd, full_path);
1050034 //
1050035 // Get the root file system inode.
1050036 //
1050037 inode = inode_get ((dev_t) 0, 1);
1050038 if (inode == NULL)
1050039 {
1050040 errset (errno);
1050041 return (NULL);
1050042 }
1050043 //
1050044 // Save the device number.
1050045 //
1050046 device = inode->sb->device;
1050047 //
1050048 // Variable `inode' already points to the root file
1050049 // system inode:
1050050 // It must be a directory!
1050051 //
1050052 status =
1050053 inode_check (inode, S_IFDIR, 1, ps->euid, ps->egid);
1050054 if (status != 0)
1050055 {
1050056 //
1050057 // Variable `errno' should be set by
1050058 // inode_check().
1050059 //
1050060 errset (errno);
1050061 inode_put (inode);
1050062 return (NULL);
1050063 }
1050064 //
1050065 // Initialize string scan: find the first path
1050066 // token, after the
1050067 // first `/'.
1050068 //
1050069 name = strtok (full_path, "/");
1050070 //
1050071 // If the original full path is just `/' the
1050072 // variable `name'
1050073 // appears as a null pointer, and the variable
1050074 // `inode' is already
1050075 // what we are looking for.
1050076 //
1050077 if (name == NULL)
1050078 {
1050079 return (inode);
1050080 }
1050081 //
1050082 // There is at least a name after `/' inside the
1050083 // original full
1050084 // path. A scan is going to start: the original
1050085 // value for variable
1050086 // `inode' is a pointer to the root directory inode.
1050087 //
1050088 for (;;)
1050089 {
1050090 //
1050091 // Find next token.
1050092 //
1050093 next = strtok (NULL, "/");
1050094 //
1050095 // Read the directory from the current inode.
1050096 //
1050097 for (offset_dir = 0;; offset_dir += size_read)
1050098 {
1050099 size_to_read = DIRECTORY_BUFFER_SIZE;
1050100 //
1050101 if ((offset_dir + size_to_read) > inode->size)
1050102 {
1050103 size_to_read = inode->size - offset_dir;
1050104 }
1050105 //
1050106 size_read =
1050107 inode_file_read (inode, offset_dir, dir,
1050108 size_to_read, NULL);
1050109 //
1050110 // The size read must be a multiple of 16.
1050111 //
1050112 size_read = ((size_read / 16) * 16);
1050113 //
1050114 // Check anyway if it is zero.
1050115 //
1050116 if (size_read == 0)
1050117 {
1050118 //
1050119 // The directory is ended: release the
1050120 // inode and return.
1050121 //
1050122 inode_put (inode);
1050123 errset (ENOENT); // No such file or
1050124 // directory.
1050125 return (NULL);
1050126 }
1050127 //
1050128 // Calculate how many directory items we
1050129 // have read.
1050130 //
1050131 dir_size_read = size_read / 16;
1050132 //
1050133 // Scan the directory to find the current
1050134 // name.
1050135 //
1050136 for (d = 0; d < dir_size_read; d++)
1050137 {
1050138 //
1050139 // Ensure to have a null terminated
1050140 // string for
1050141 // the name found.
1050142 //
1050143 memcpy (dir_name, dir[d].name,
1050144 (size_t) NAME_MAX);
1050145 dir_name[NAME_MAX] = 0;
1050146 //
1050147 comp = strcmp (name, dir_name);
1050148 if (comp == 0 && dir[d].ino != 0)
1050149 {
1050150 //
1050151 // Found the name and verified that
1050152 // it has a link to
1050153 // a inode. Now release the
1050154 // directory inode.
1050155 //
1050156 inode_put (inode);
1050157 //
1050158 // Get next inode and break the
1050159 // loop.
1050160 //
1050161 inode = inode_get (device, dir[d].ino);
1050162 break;
1050163 }
1050164 }
1050165 //
1050166 // If index `d' is in a valid range, the
1050167 // name was found.
1050168 //
1050169 if (d < dir_size_read)
1050170 {
1050171 //
1050172 // The name was found.
1050173 //
1050174 break;
1050175 }
1050176 }
1050177 //
1050178 // If the function is still working, a file or a
1050179 // directory
1050180 // was found: see if there is another name after
1050181 // this one
1050182 // to look for. If there isn't, just break the
1050183 // loop.
1050184 //
1050185 if (next == NULL)
1050186 {
1050187 //
1050188 // As no other tokens are to be found, break
1050189 // the loop.
1050190 //
1050191 break;
1050192 }
1050193 //
1050194 // As there is another name after the current
1050195 // one,
1050196 // the current file must be a directory.
1050197 //
1050198 status =
1050199 inode_check (inode, S_IFDIR, 1, ps->euid, ps->egid);
1050200 if (status != 0)
1050201 {
1050202 //
1050203 // Variable `errno' is set by
1050204 // `inode_check()'.
1050205 //
1050206 errset (errno);
1050207 inode_put (inode);
1050208 return (NULL);
1050209 }
1050210 //
1050211 // The inode is a directory and the user has the
1050212 // necessary
1050213 // permissions: check if it is a mount point and
1050214 // go to the
1050215 // new device root directory if necessary.
1050216 //
1050217 if (inode->sb_attached != NULL)
1050218 {
1050219 //
1050220 // Must find the root directory for the new
1050221 // device, and
1050222 // then go to that inode.
1050223 //
1050224 device = inode->sb_attached->device;
1050225 inode_put (inode);
1050226 inode = inode_get (device, 1);
1050227 status = inode_check (inode, S_IFDIR, 1,
1050228 ps->euid, ps->egid);
1050229 if (status != 0)
1050230 {
1050231 inode_put (inode);
1050232 return (NULL);
1050233 }
1050234 }
1050235 //
1050236 // As a directory was found, and another token
1050237 // follows it,
1050238 // must continue the token scan.
1050239 //
1050240 name = next;
1050241 }
1050242 //
1050243 // Current inode found is the file represented by
1050244 // the requested
1050245 // path.
1050246 //
1050247 return (inode);
1050248 }
|
|
94.5.31
kernel/fs/path_inode_link.c
Si veda la sezione 93.6.42.
1060001 #include <kernel/fs.h>
1060002 #include <errno.h>
1060003 #include <kernel/proc.h>
1060004 #include <libgen.h>
1060005 //----------------------------------------------------------
1060006 inode_t *
1060007 path_inode_link (pid_t pid, const char *path,
1060008 inode_t * inode, mode_t mode)
1060009 {
1060010 proc_t *ps;
1060011 char buffer[SB_MAX_ZONE_SIZE];
1060012 off_t start;
1060013 int d; // Directory index.
1060014 ssize_t size_read;
1060015 ssize_t size_written;
1060016 directory_t *dir = (directory_t *) buffer;
1060017 char path_copy1[PATH_MAX];
1060018 char path_copy2[PATH_MAX];
1060019 char *path_directory;
1060020 char *path_name;
1060021 inode_t *inode_directory;
1060022 inode_t *inode_new;
1060023 dev_t device;
1060024 int status;
1060025 //
1060026 // Check arguments.
1060027 //
1060028 if (path == NULL || strlen (path) == 0)
1060029 {
1060030 errset (EINVAL); // Invalid argument:
1060031 return (NULL); // the path is mandatory.
1060032 }
1060033 //
1060034 if (inode == NULL && mode == 0)
1060035 {
1060036 errset (EINVAL); // Invalid argument: if the
1060037 // inode is to
1060038 return (NULL); // be created, the mode is
1060039 // mandatory.
1060040 }
1060041 //
1060042 if (inode != NULL)
1060043 {
1060044 if (mode != 0)
1060045 {
1060046 errset (EINVAL); // Invalid argument:
1060047 // if the inode is
1060048 return (NULL); // already present,
1060049 // the creation mode
1060050 } // must not be given.
1060051 if (S_ISDIR (inode->mode))
1060052 {
1060053 errset (EPERM); // Operation not
1060054 // permitted.
1060055 return (NULL); // Refuse to link
1060056 // directory.
1060057 }
1060058 if (inode->links >= LINK_MAX)
1060059 {
1060060 errset (EMLINK); // Too many links.
1060061 return (NULL);
1060062 }
1060063 }
1060064 //
1060065 // Get process.
1060066 //
1060067 ps = proc_reference (pid);
1060068 //
1060069 // If the destination path already exists, the link
1060070 // cannot be made.
1060071 // It does not matter if the inode is known or not.
1060072 //
1060073 inode_new = path_inode ((uid_t) 0, path);
1060074 if (inode_new != NULL)
1060075 {
1060076 //
1060077 // A file already exists with the same name.
1060078 //
1060079 inode_put (inode_new);
1060080 errset (EEXIST); // File exists.
1060081 return (NULL);
1060082 }
1060083 //
1060084 // At this point, `inode_new' is `NULL'.
1060085 // Copy the source path inside the directory path
1060086 // and name arrays.
1060087 //
1060088 strncpy (path_copy1, path, PATH_MAX);
1060089 strncpy (path_copy2, path, PATH_MAX);
1060090 //
1060091 // Reduce to directory name and find the last name.
1060092 //
1060093 path_directory = dirname (path_copy1);
1060094 path_name = basename (path_copy2);
1060095 if (strlen (path_directory) == 0
1060096 || strlen (path_name) == 0)
1060097 {
1060098 errset (EACCES); // Permission denied: maybe
1060099 // the
1060100 // original path is the root directory
1060101 // and cannot find a previous directory.
1060102 return (NULL);
1060103 }
1060104 //
1060105 // Get the directory inode.
1060106 //
1060107 inode_directory = path_inode (pid, path_directory);
1060108 if (inode_directory == NULL)
1060109 {
1060110 errset (errno);
1060111 return (NULL);
1060112 }
1060113 //
1060114 // Check if something is mounted on it.
1060115 //
1060116 if (inode_directory->sb_attached != NULL)
1060117 {
1060118 //
1060119 // Must select the right directory.
1060120 //
1060121 device = inode_directory->sb_attached->device;
1060122 inode_put (inode_directory);
1060123 inode_directory = inode_get (device, 1);
1060124 if (inode_directory == NULL)
1060125 {
1060126 return (NULL);
1060127 }
1060128 }
1060129 //
1060130 // If the inode to link is known, check if the
1060131 // selected directory
1060132 // has the same super block than the inode to link.
1060133 //
1060134 if (inode != NULL && inode_directory->sb != inode->sb)
1060135 {
1060136 inode_put (inode_directory);
1060137 errset (ENOENT); // No such file or directory.
1060138 return (NULL);
1060139 }
1060140 //
1060141 // Check if write is allowed for the file system.
1060142 //
1060143 if (inode_directory->sb->options & MOUNT_RO)
1060144 {
1060145 inode_put (inode_directory);
1060146 errset (EROFS); // Read-only file system.
1060147 return (NULL);
1060148 }
1060149 //
1060150 // Verify access permissions for the directory. The
1060151 // number "3" means
1060152 // that the user must have access permission and
1060153 // write permission:
1060154 // "-wx" == 2+1 == 3.
1060155 //
1060156 status = inode_check (inode_directory, S_IFDIR, 3,
1060157 ps->euid, ps->egid);
1060158 if (status != 0)
1060159 {
1060160 inode_put (inode_directory);
1060161 return (NULL);
1060162 }
1060163 //
1060164 // If the inode to link was not specified, it must
1060165 // be created.
1060166 // From now on, the inode is referenced with the
1060167 // variable
1060168 // `inode_new'.
1060169 //
1060170 inode_new = inode;
1060171 //
1060172 if (inode_new == NULL)
1060173 {
1060174 inode_new =
1060175 inode_alloc (inode_directory->sb->device, mode,
1060176 ps->euid, ps->egid);
1060177 if (inode_new == NULL)
1060178 {
1060179 //
1060180 // The inode allocation failed, so, also the
1060181 // directory
1060182 // must be released, before return.
1060183 //
1060184 inode_put (inode_directory);
1060185 return (NULL);
1060186 }
1060187 }
1060188 //
1060189 // Read the directory content and try to add the new
1060190 // item.
1060191 //
1060192 for (start = 0;
1060193 start < inode_directory->size;
1060194 start += inode_directory->sb->blksize)
1060195 {
1060196 size_read =
1060197 inode_file_read (inode_directory, start,
1060198 buffer,
1060199 inode_directory->sb->blksize,
1060200 NULL);
1060201 if (size_read < sizeof (directory_t))
1060202 {
1060203 break;
1060204 }
1060205 //
1060206 // Scan the directory portion just read, for an
1060207 // unused item.
1060208 //
1060209 dir = (directory_t *) buffer;
1060210 for (d = 0; d < size_read;
1060211 d += (sizeof (directory_t)), dir++)
1060212 {
1060213 if (dir->ino == 0)
1060214 {
1060215 //
1060216 // Found an empty directory item: link
1060217 // the inode.
1060218 //
1060219 dir->ino = inode_new->ino;
1060220 strncpy (dir->name, path_name, NAME_MAX);
1060221 inode_new->links++;
1060222 inode_new->changed = 1;
1060223 //
1060224 // Update the directory inside the file
1060225 // system.
1060226 //
1060227 size_written =
1060228 inode_file_write (inode_directory,
1060229 start, buffer, size_read);
1060230 if (size_written != size_read)
1060231 {
1060232 //
1060233 // Write problem: release the
1060234 // directory and return.
1060235 //
1060236 inode_put (inode_directory);
1060237 errset (EUNKNOWN);
1060238 return (NULL);
1060239 }
1060240 //
1060241 // Save the new inode, release the
1060242 // directory and return
1060243 // the linked inode.
1060244 //
1060245 inode_save (inode_new);
1060246 inode_put (inode_directory);
1060247 return (inode_new);
1060248 }
1060249 }
1060250 }
1060251 //
1060252 // The directory don't have a free item and one must
1060253 // be appended.
1060254 //
1060255 dir = (directory_t *) buffer;
1060256 start = inode_directory->size;
1060257 //
1060258 // Prepare the buffer with the link.
1060259 //
1060260 dir->ino = inode_new->ino;
1060261 strncpy (dir->name, path_name, NAME_MAX);
1060262 inode_new->links++;
1060263 inode_new->changed = 1;
1060264 //
1060265 // Append the buffer to the directory.
1060266 //
1060267 size_written =
1060268 inode_file_write (inode_directory, start, buffer,
1060269 (sizeof (directory_t)));
1060270 if (size_written != (sizeof (directory_t)))
1060271 {
1060272 //
1060273 // Problem updating the directory: release it
1060274 // and return.
1060275 //
1060276 inode_put (inode_directory);
1060277 errset (EUNKNOWN);
1060278 return (NULL);
1060279 }
1060280 //
1060281 // Close access to the directory inode and save the
1060282 // other inode,
1060283 // with updated link count.
1060284 //
1060285 inode_put (inode_directory);
1060286 inode_save (inode_new);
1060287 //
1060288 // Return successfully.
1060289 //
1060290 return (inode_new);
1060291 }
|
|
94.5.32
kernel/fs/sb_inode_status.c
Si veda la sezione 93.6.26.
1070001 #include <kernel/fs.h>
1070002 #include <errno.h>
1070003 //----------------------------------------------------------
1070004 int
1070005 sb_inode_status (sb_t * sb, ino_t ino)
1070006 {
1070007 int map_element;
1070008 int map_bit;
1070009 int map_mask;
1070010 //
1070011 // Check arguments.
1070012 //
1070013 if (ino == 0 || sb == NULL)
1070014 {
1070015 errset (EINVAL); // Invalid argument.
1070016 return (-1);
1070017 }
1070018 //
1070019 // Calculate the map element, the map bit and the
1070020 // map mask.
1070021 //
1070022 map_element = ino / 16;
1070023 map_bit = ino % 16;
1070024 map_mask = 1 << map_bit;
1070025 //
1070026 // Check the inode and return.
1070027 //
1070028 if (sb->map_inode[map_element] & map_mask)
1070029 {
1070030 return (1); // True.
1070031 }
1070032 else
1070033 {
1070034 return (0); // False.
1070035 }
1070036 }
|
|
94.5.33
kernel/fs/sb_mount.c
Si veda la sezione 93.6.27.
1080001 #include <kernel/fs.h>
1080002 #include <errno.h>
1080003 #include <kernel/dev.h>
1080004 #include <kernel/lib_k.h>
1080005 #include <kernel/dm.h>
1080006 #include <kernel/part.h>
1080007 //----------------------------------------------------------
1080008 sb_t *
1080009 sb_mount (dev_t device, inode_t ** inode_mnt, int options)
1080010 {
1080011 sb_t *sb;
1080012 ssize_t size_read;
1080013 addr_t start;
1080014 int m;
1080015 size_t size_sb;
1080016 size_t size_map;
1080017 int dev_major = major (device);
1080018 int dev_minor = minor (device);
1080019 int p = dev_minor & 0x000F;
1080020 int d = ((dev_minor & 0x00F0) >> 4);
1080021 //
1080022 // Find if it is already mounted.
1080023 //
1080024 sb = sb_reference (device);
1080025 if (sb != NULL)
1080026 {
1080027 errset (EBUSY); // Device or resource busy:
1080028 // device
1080029 return (NULL); // already mounted.
1080030 }
1080031 //
1080032 // Find if `*inode_mnt' is already mounting
1080033 // something.
1080034 //
1080035 if (*inode_mnt != NULL
1080036 && (*inode_mnt)->sb_attached != NULL)
1080037 {
1080038 errset (EBUSY); // Device or resource busy:
1080039 // mount point
1080040 return (NULL); // already used.
1080041 }
1080042 //
1080043 // If it is a partition, find if it can be mounted.
1080044 //
1080045 if ((dev_major == DEV_DM_MAJOR) && (p));
1080046 {
1080047 //
1080048 // It is a partition.
1080049 //
1080050 if (dm_table[d].part[p].type != PART_TYPE_MINIX)
1080051 {
1080052 errset (E_PART_TYPE_NOT_MINIX); // Not Minix!
1080053 return (NULL); // Cannot mount.
1080054 }
1080055 }
1080056 //
1080057 // The inode is not yet mounting anything, or it is
1080058 // new: find a free
1080059 // slot inside the super block table.
1080060 //
1080061 sb = sb_reference ((dev_t) - 1);
1080062 if (sb == NULL)
1080063 {
1080064 errset (EBUSY); // Device or resource busy:
1080065 return (NULL); // no free slots.
1080066 }
1080067 //
1080068 // A free slot was found: the super block header
1080069 // must be loaded, but
1080070 // before it is necessary to calculate the header
1080071 // size to be read.
1080072 //
1080073 size_sb = offsetof (sb_t, device);
1080074 //
1080075 // Then fix the starting point.
1080076 //
1080077 start = 1024; // After boot block.
1080078 //
1080079 // Read the file system super block header.
1080080 //
1080081 size_read =
1080082 dev_io ((pid_t) 0, device, DEV_READ, start, sb,
1080083 size_sb, NULL);
1080084 if (size_read != size_sb)
1080085 {
1080086 errset (EIO); // I/O error.
1080087 return (NULL);
1080088 }
1080089 //
1080090 // Save some more data.
1080091 //
1080092 sb->device = device;
1080093 sb->options = options;
1080094 sb->inode_mounted_on = *inode_mnt;
1080095 sb->blksize = (1024 << sb->log2_size_zone);
1080096 //
1080097 // Check if the super block data is valid.
1080098 //
1080099 if (sb->magic_number != 0x137F)
1080100 {
1080101 errset (ENODEV); // No such device: unsupported
1080102 sb->device = 0; // file system type.
1080103 return (NULL);
1080104 }
1080105 if (sb->map_inode_blocks > SB_MAX_INODE_BLOCKS)
1080106 {
1080107 errset (E_MAP_INODE_TOO_BIG);
1080108 return (NULL);
1080109 }
1080110 if (sb->map_zone_blocks > SB_MAX_ZONE_BLOCKS)
1080111 {
1080112 errset (E_MAP_ZONE_TOO_BIG);
1080113 return (NULL);
1080114 }
1080115 if (sb->blksize > SB_MAX_ZONE_SIZE)
1080116 {
1080117 errset (E_DATA_ZONE_TOO_BIG);
1080118 return (NULL);
1080119 }
1080120 //
1080121 // A right super block header was loaded from disk,
1080122 // now load the super block inode bit map.
1080123 //
1080124 start = 1024; // After boot block.
1080125 start += 1024; // After super block.
1080126 //
1080127 // Reset map in memory before loading.
1080128 //
1080129 for (m = 0; m < SB_MAP_INODE_SIZE; m++) // [2]
1080130 {
1080131 sb->map_inode[m] = 0xFFFF; // [2]
1080132 }
1080133 size_map = sb->map_inode_blocks * 1024;
1080134 size_read =
1080135 dev_io ((pid_t) - 1, sb->device, DEV_READ, start,
1080136 sb->map_inode, size_map, NULL);
1080137 if (size_read != size_map)
1080138 {
1080139 errset (EIO); // I/O error.
1080140 return (NULL);
1080141 }
1080142 //
1080143 // Load the super block zone bit map.
1080144 //
1080145 // After boot block:
1080146 //
1080147 start = 1024;
1080148 //
1080149 // After the super block:
1080150 //
1080151 start += 1024;
1080152 //
1080153 // After inode bit map:
1080154 //
1080155 start += (sb->map_inode_blocks * 1024);
1080156 //
1080157 // Reset map in memory, before loading.
1080158 //
1080159 for (m = 0; m < SB_MAP_ZONE_SIZE; m++)
1080160 {
1080161 sb->map_zone[m] = 0xFFFF;
1080162 }
1080163 //
1080164 size_map = sb->map_zone_blocks * 1024;
1080165 size_read =
1080166 dev_io ((pid_t) - 1, sb->device, DEV_READ, start,
1080167 sb->map_zone, size_map, NULL);
1080168 if (size_read != size_map)
1080169 {
1080170 errset (EIO); // I/O error.
1080171 return (NULL);
1080172 }
1080173 //
1080174 // Check the inode that should mount the super
1080175 // block. If `*inode_mnt' is `NULL', then it is meant
1080176 // to be the first mount of the root file system.
1080177 // In such case, the inode must be loaded too,
1080178 // and the value for `*inode_mnt' must be modified.
1080179 //
1080180 if (*inode_mnt == NULL)
1080181 {
1080182 *inode_mnt = inode_get (device, 1);
1080183 }
1080184 //
1080185 // Check for a valid value.
1080186 //
1080187 if (*inode_mnt == NULL)
1080188 {
1080189 //
1080190 // This is bad!
1080191 //
1080192 errset (EUNKNOWN); // Unknown error.
1080193 return (NULL);
1080194 }
1080195 //
1080196 // A valid inode is available for the mount.
1080197 //
1080198 (*inode_mnt)->sb_attached = sb;
1080199 //
1080200 // Update the super block too.
1080201 //
1080202 sb->inode_mounted_on = *inode_mnt;
1080203 //
1080204 // Return the super block pointer.
1080205 //
1080206 return (sb);
1080207 }
|
|
94.5.34
kernel/fs/sb_print.c
Si veda la sezione 93.6.28.
1090001 #include <sys/os32.h>
1090002 #include <kernel/fs.h>
1090003 #include <kernel/lib_k.h>
1090004 //----------------------------------------------------------
1090005 void
1090006 sb_print (void)
1090007 {
1090008 int s;
1090009 //
1090010 k_printf
1090011 (" mnt 1st zone max file "
1090012 " inode zone \n");
1090013 k_printf
1090014 ("dev dev inodes blocks dz size size KiB "
1090015 "blocks blocks\n");
1090016 //
1090017 for (s = 0; s < SB_MAX_SLOTS; s++)
1090018 {
1090019 if (sb_table[s].device == 0)
1090020 {
1090021 continue;
1090022 }
1090023 k_printf
1090024 ("%04x %04x % 6i % 6i % 3i "
1090025 "% 4i % 8i % 6i % 6i\n",
1090026 sb_table[s].device,
1090027 sb_table[s].inode_mounted_on->sb_attached->device,
1090028 sb_table[s].inodes, sb_table[s].zones,
1090029 sb_table[s].first_data_zone,
1090030 (1024 << sb_table[s].log2_size_zone),
1090031 sb_table[s].max_file_size / 1024,
1090032 sb_table[s].map_inode_blocks,
1090033 sb_table[s].map_zone_blocks);
1090034 }
1090035 }
|
|
94.5.35
kernel/fs/sb_reference.c
Si veda la sezione 93.6.29.
1100001 #include <kernel/fs.h>
1100002 #include <errno.h>
1100003 //----------------------------------------------------------
1100004 sb_t *
1100005 sb_reference (dev_t device)
1100006 {
1100007 int s; // Slot index.
1100008 //
1100009 // If device is zero, a reference to the whole table
1100010 // is returned.
1100011 //
1100012 if (device == 0)
1100013 {
1100014 return (sb_table);
1100015 }
1100016 //
1100017 // If device is ((dev_t) -1), a reference to a free
1100018 // slot is
1100019 // returned.
1100020 //
1100021 if (device == ((dev_t) - 1))
1100022 {
1100023 for (s = 0; s < SB_MAX_SLOTS; s++)
1100024 {
1100025 if (sb_table[s].device == 0)
1100026 {
1100027 return (&sb_table[s]);
1100028 }
1100029 }
1100030 return (NULL);
1100031 }
1100032 //
1100033 // A device was selected: find the super block
1100034 // associated to it.
1100035 //
1100036 for (s = 0; s < SB_MAX_SLOTS; s++)
1100037 {
1100038 if (sb_table[s].device == device)
1100039 {
1100040 return (&sb_table[s]);
1100041 }
1100042 }
1100043 //
1100044 // The super block was not found.
1100045 //
1100046 return (NULL);
1100047 }
|
|
94.5.36
kernel/fs/sb_save.c
Si veda la sezione 93.6.30.
1110001 #include <kernel/fs.h>
1110002 #include <errno.h>
1110003 #include <kernel/dev.h>
1110004 //----------------------------------------------------------
1110005 int
1110006 sb_save (sb_t * sb)
1110007 {
1110008 ssize_t size_written;
1110009 addr_t start;
1110010 size_t size_map;
1110011 //
1110012 // Check for valid argument.
1110013 //
1110014 if (sb == NULL)
1110015 {
1110016 errset (EINVAL); // Invalid argument.
1110017 return (-1);
1110018 }
1110019 //
1110020 // Check if the super block changed for some reason
1110021 // (only the inode and the zone maps can change
1110022 // really).
1110023 //
1110024 if (!sb->changed)
1110025 {
1110026 //
1110027 // Nothing to save.
1110028 //
1110029 return (0);
1110030 }
1110031 //
1110032 // Something inside the super block changed: start
1110033 // the procedure to save the inode map (recall that
1110034 // the super block header is not saved, because it
1110035 // never changes).
1110036 //
1110037 start = 1024; // After boot block.
1110038 start += 1024; // After super block.
1110039 size_map = sb->map_inode_blocks * 1024;
1110040 size_written =
1110041 dev_io ((pid_t) - 1, sb->device, DEV_WRITE, start,
1110042 sb->map_inode, size_map, NULL);
1110043 if (size_written != size_map)
1110044 {
1110045 //
1110046 // Error writing the map.
1110047 //
1110048 errset (EIO); // I/O error.
1110049 return (-1);
1110050 }
1110051 //
1110052 // Start the procedure to save the zone map.
1110053 //
1110054 start = 1024; // After boot block.
1110055 start += 1024; // After super block.
1110056 start += (sb->map_inode_blocks * 1024); // After
1110057 // inode bit
1110058 // map.
1110059 size_map = sb->map_zone_blocks * 1024;
1110060 size_written =
1110061 dev_io ((pid_t) - 1, sb->device, DEV_WRITE, start,
1110062 sb->map_zone, size_map, NULL);
1110063 if (size_written != size_map)
1110064 {
1110065 //
1110066 // Error writing the map.
1110067 //
1110068 errset (EIO); // I/O error.
1110069 return (-1);
1110070 }
1110071 //
1110072 // Super block saved.
1110073 //
1110074 sb->changed = 0;
1110075 //
1110076 return (0);
1110077 }
|
|
94.5.37
kernel/fs/sb_zone_status.c
Si veda la sezione 93.6.26.
1120001 #include <kernel/fs.h>
1120002 #include <errno.h>
1120003 //----------------------------------------------------------
1120004 int
1120005 sb_zone_status (sb_t * sb, zno_t zone)
1120006 {
1120007 int map_element;
1120008 int map_bit;
1120009 int map_mask;
1120010 //
1120011 // Check arguments.
1120012 //
1120013 if (zone == 0 || sb == NULL)
1120014 {
1120015 errset (EINVAL); // Invalid argument.
1120016 return (-1);
1120017 }
1120018 //
1120019 // Calculate the map element, the map bit and the
1120020 // map mask.
1120021 //
1120022 map_element = zone / 16;
1120023 map_bit = zone % 16;
1120024 map_mask = 1 << map_bit;
1120025 //
1120026 // Check the zone and return.
1120027 //
1120028 if (sb->map_zone[map_element] & map_mask)
1120029 {
1120030 return (1); // True.
1120031 }
1120032 else
1120033 {
1120034 return (0); // False.
1120035 }
1120036 }
|
|
94.5.38
kernel/fs/sock_free_port.c
Si veda la sezione 93.6.32.
1130001 #include <kernel/fs.h>
1130002 #include <errno.h>
1130003 #include <fcntl.h>
1130004 //----------------------------------------------------------
1130005 h_port_t
1130006 sock_free_port (void)
1130007 {
1130008 int skn;
1130009 h_port_t lport;
1130010 //
1130011 for (lport = 0xFFFF; lport >= 1024; lport--)
1130012 {
1130013 for (skn = 0; skn < SOCK_MAX_SLOTS; skn++)
1130014 {
1130015 if (sock_table[skn].lport == lport)
1130016 {
1130017 //
1130018 // The port is used.
1130019 //
1130020 break;
1130021 }
1130022 }
1130023 if (sock_table[skn].lport != lport)
1130024 {
1130025 //
1130026 // The port is new.
1130027 //
1130028 return (lport);
1130029 }
1130030 }
1130031 //
1130032 // If we are here, no free port was found.
1130033 //
1130034 return ((h_port_t) 0);
1130035 }
|
|
94.5.39
kernel/fs/sock_reference.c
Si veda la sezione 93.6.33.
1140001 #include <kernel/fs.h>
1140002 #include <errno.h>
1140003 #include <fcntl.h>
1140004 //----------------------------------------------------------
1140005 sock_t *
1140006 sock_reference (int skn)
1140007 {
1140008 //
1140009 // Check type of request.
1140010 //
1140011 if (skn < 0)
1140012 {
1140013 //
1140014 // Find a free slot.
1140015 //
1140016 for (skn = 0; skn < SOCK_MAX_SLOTS; skn++)
1140017 {
1140018 if (sock_table[skn].active == 0)
1140019 {
1140020 return (&sock_table[skn]);
1140021 }
1140022 }
1140023 return (NULL);
1140024 }
1140025 else if (skn > SOCK_MAX_SLOTS)
1140026 {
1140027 return (NULL);
1140028 }
1140029 else
1140030 {
1140031 return (&sock_table[skn]);
1140032 }
1140033 }
|
|
94.5.40
kernel/fs/zone_alloc.c
Si veda la sezione 93.6.34.
1150001 #include <kernel/fs.h>
1150002 #include <kernel/dev.h>
1150003 #include <errno.h>
1150004 //----------------------------------------------------------
1150005 zno_t
1150006 zone_alloc (sb_t * sb)
1150007 {
1150008 int m; // Index inside the inode map.
1150009 int map_element;
1150010 int map_bit;
1150011 int map_mask;
1150012 zno_t zone;
1150013 char buffer[SB_MAX_ZONE_SIZE];
1150014 int status;
1150015 //
1150016 // Verify if write is allowed.
1150017 //
1150018 if (sb->options & MOUNT_RO)
1150019 {
1150020 errset (EROFS); // Read-only file system.
1150021 return ((zno_t) 0);
1150022 }
1150023 //
1150024 // Write allowed: scan the zone map, to find a free
1150025 // zone. If a free zone can be found, allocate it
1150026 // inside the map.
1150027 // Index `m' starts from one, because the first bit
1150028 // of the map is reserved for a `zero' data-zone
1150029 // that does not exist: the second bit is for the
1150030 // real first data-zone.
1150031 //
1150032 for (zone = 0, m = 1; m < (SB_MAP_ZONE_SIZE * 16); m++)
1150033 {
1150034 map_element = m / 16;
1150035 map_bit = m % 16;
1150036 map_mask = 1 << map_bit;
1150037 if (!(sb->map_zone[map_element] & map_mask))
1150038 {
1150039 //
1150040 // Found a free place: set the map.
1150041 //
1150042 sb->map_zone[map_element] |= map_mask;
1150043 sb->changed = 1;
1150044 //
1150045 // The *second* bit inside the map is for
1150046 // the first data zone (the zone after the
1150047 // inode table inside the file system),
1150048 // because the first is for a special
1150049 // `zero' data zone, not really used.
1150050 //
1150051 zone = sb->first_data_zone + m - 1; // Found
1150052 // a free
1150053 // zone.
1150054 //
1150055 // If the zone is outside the disk size, let
1150056 // set the map bit, but reset variable
1150057 // `zone'.
1150058 //
1150059 if (zone >= sb->zones)
1150060 {
1150061 zone = 0;
1150062 }
1150063 else
1150064 {
1150065 break;
1150066 }
1150067 }
1150068 }
1150069 if (zone == 0)
1150070 {
1150071 errset (ENOSPC); // No space left on device.
1150072 return ((zno_t) 0);
1150073 }
1150074 //
1150075 // A free zone was found and the map was modified
1150076 // inside
1150077 // the super block in memory. The zone must be
1150078 // cleared.
1150079 //
1150080 status = zone_write (sb, zone, buffer);
1150081 if (status != 0)
1150082 {
1150083 zone_free (sb, zone);
1150084 return ((zno_t) 0);
1150085 }
1150086 //
1150087 // A zone was allocated: return the number.
1150088 //
1150089 return (zone);
1150090 }
|
|
94.5.41
kernel/fs/zone_free.c
Si veda la sezione 93.6.34.
1160001 #include <kernel/fs.h>
1160002 #include <kernel/dev.h>
1160003 #include <errno.h>
1160004 //----------------------------------------------------------
1160005 int
1160006 zone_free (sb_t * sb, zno_t zone)
1160007 {
1160008 int map_element;
1160009 int map_bit;
1160010 int map_mask;
1160011 //
1160012 // Check arguments.
1160013 //
1160014 if (sb == NULL || zone < sb->first_data_zone)
1160015 {
1160016 errset (EINVAL); // Invalid argument.
1160017 return (-1);
1160018 }
1160019 //
1160020 // Calculate the map element, the map bit and the
1160021 // map mask.
1160022 //
1160023 // The *second* bit inside the map is for the first
1160024 // data-zone
1160025 // (the zone after the inode table inside the file
1160026 // system),
1160027 // because the first is for a special `zero'
1160028 // data-zone, not
1160029 // really used.
1160030 //
1160031 map_element = (zone - sb->first_data_zone + 1) / 16;
1160032 map_bit = (zone - sb->first_data_zone + 1) % 16;
1160033 map_mask = 1 << map_bit;
1160034 //
1160035 // Verify if the requested zone is inside the file
1160036 // system area.
1160037 //
1160038 if (zone >= sb->zones)
1160039 {
1160040 errset (EINVAL); // Invalid argument.
1160041 return (-1);
1160042 }
1160043 //
1160044 // Free the zone and return.
1160045 //
1160046 if (sb->map_zone[map_element] & map_mask)
1160047 {
1160048 sb->map_zone[map_element] &= ~map_mask;
1160049 sb->changed = 1;
1160050 return (0);
1160051 }
1160052 else
1160053 {
1160054 errset (EUNKNOWN); // The zone was
1160055 // already free.
1160056 return (-1);
1160057 }
1160058 }
|
|
94.5.42
kernel/fs/zone_print.c
Si veda la sezione 93.6.36.
1170001 #include <sys/os32.h>
1170002 #include <kernel/fs.h>
1170003 #include <kernel/dev.h>
1170004 #include <errno.h>
1170005 //----------------------------------------------------------
1170006 void
1170007 zone_print (sb_t * sb, zno_t zone)
1170008 {
1170009 char buffer[SB_MAX_ZONE_SIZE];
1170010 int status;
1170011 int i;
1170012 int x;
1170013 //
1170014 status = zone_read (sb, zone, buffer);
1170015 //
1170016 if (status < 0)
1170017 {
1170018 k_perror (NULL);
1170019 return;
1170020 }
1170021 //
1170022 // Print.
1170023 //
1170024 k_printf
1170025 ("dev: 0x%04x, first dzone: %i zone read: %i\n",
1170026 sb->device, sb->first_data_zone, zone);
1170027 //
1170028 // Will print at most the first 256 byte only!
1170029 //
1170030 for (i = 0; i < sb->blksize && i < 256; i++)
1170031 {
1170032 k_printf ("%02x ", buffer[i]);
1170033 x = (i + 1) % 4;
1170034 if (x == 0 && i > 0)
1170035 {
1170036 k_printf ("| ");
1170037 }
1170038 x = (i + 1) % 16;
1170039 if (x == 0 && i > 0)
1170040 {
1170041 k_printf ("\n");
1170042 }
1170043 }
1170044 }
|
|
94.5.43
kernel/fs/zone_read.c
Si veda la sezione 93.6.37.
1180001 #include <sys/os32.h>
1180002 #include <kernel/fs.h>
1180003 #include <kernel/dev.h>
1180004 #include <errno.h>
1180005 //----------------------------------------------------------
1180006 int
1180007 zone_read (sb_t * sb, zno_t zone, void *buffer)
1180008 {
1180009 size_t size_zone;
1180010 off_t off_start;
1180011 ssize_t size_read;
1180012 //
1180013 // Verify if the requested zone is inside the file
1180014 // system area.
1180015 //
1180016 if (zone >= sb->zones)
1180017 {
1180018 errset (EINVAL); // Invalid argument.
1180019 return (-1);
1180020 }
1180021 //
1180022 // Calculate start position.
1180023 //
1180024 size_zone = 1024 << sb->log2_size_zone;
1180025 off_start = zone;
1180026 off_start *= size_zone;
1180027 //
1180028 // Read from device to the buffer.
1180029 //
1180030 size_read =
1180031 dev_io ((pid_t) - 1, sb->device, DEV_READ,
1180032 off_start, buffer, size_zone, NULL);
1180033 if (size_read != size_zone)
1180034 {
1180035 errset (EIO); // I/O error.
1180036 return (-1);
1180037 }
1180038 else
1180039 {
1180040 return (0);
1180041 }
1180042 }
|
|
94.5.44
kernel/fs/zone_write.c
Si veda la sezione 93.6.37.
1190001 #include <kernel/fs.h>
1190002 #include <kernel/dev.h>
1190003 #include <errno.h>
1190004 //----------------------------------------------------------
1190005 int
1190006 zone_write (sb_t * sb, zno_t zone, void *buffer)
1190007 {
1190008 size_t size_zone;
1190009 off_t off_start;
1190010 ssize_t size_written;
1190011 //
1190012 // Verify if write is allowed.
1190013 //
1190014 if (sb->options & MOUNT_RO)
1190015 {
1190016 errset (EROFS); // Read-only file system.
1190017 return (-1);
1190018 }
1190019 //
1190020 // Verify if the requested zone is inside the file
1190021 // system area.
1190022 //
1190023 if (zone >= sb->zones)
1190024 {
1190025 errset (EINVAL); // Invalid argument.
1190026 return (-1);
1190027 }
1190028 //
1190029 // Write is allowed: calculate start position.
1190030 //
1190031 size_zone = 1024 << sb->log2_size_zone;
1190032 off_start = zone;
1190033 off_start *= size_zone;
1190034 //
1190035 // Write the buffer to the device.
1190036 //
1190037 size_written =
1190038 dev_io ((pid_t) - 1, sb->device, DEV_WRITE,
1190039 off_start, buffer, size_zone, NULL);
1190040 if (size_written != size_zone)
1190041 {
1190042 errset (EIO); // I/O error.
1190043 return (-1);
1190044 }
1190045 else
1190046 {
1190047 return (0);
1190048 }
1190049 }
|
|
94.6
os32: «kernel/ibm_i386.h»
Si veda la sezione 93.7.
1200001 #ifndef _KERNEL_IBM_I386_H
1200002 #define _KERNEL_IBM_I386_H 1
1200003 //----------------------------------------------------------
1200004 #include <stdint.h>
1200005 #include <inttypes.h>
1200006 #include <stdbool.h>
1200007 #include <stdarg.h>
1200008 //----------------------------------------------------------
1200009 // GDT
1200010 //----------------------------------------------------------
1200011 #define GDT_ITEMS 256 // Max is 8192 items.
1200012 //
1200013 typedef struct
1200014 {
1200015 uint32_t limit_a:16, base_a:16;
1200016 uint32_t base_b:8,
1200017 accessed:1,
1200018 write_execute:1,
1200019 expansion_conforming:1,
1200020 code_or_data:1,
1200021 code_data_or_system:1,
1200022 dpl:2,
1200023 present:1,
1200024 limit_b:4,
1200025 available:1, reserved:1, big:1, granularity:1, base_c:8;
1200026 } gdt_t;
1200027 //
1200028 extern gdt_t gdt_table[GDT_ITEMS];
1200029 //----------------------------------------------------------
1200030 typedef struct
1200031 {
1200032 uint16_t limit;
1200033 uint32_t base;
1200034 } __attribute__ ((packed)) gdtr_t; // [1]
1200035 //
1200036 extern gdtr_t gdt_register;
1200037 //
1200038 // [1] It is necessary that the structure be compact,
1200039 // so that it uses exactly 48 bits. That is why the
1200040 // attribute `packed' for the GNU C compiler is
1200041 // used.
1200042 //----------------------------------------------------------
1200043 int gdt_segment (int segment, uint32_t base,
1200044 uint32_t limit, bool present,
1200045 bool code, unsigned char dpl);
1200046 //
1200047 void gdt_print (void *gdtr, unsigned int first,
1200048 unsigned int last);
1200049 void gdt_load (void *gdtr);
1200050 void gdt (void);
1200051 //
1200052 // Segment 0 is not used,
1200053 // segment 1 is for kernel code,
1200054 // segment 2 is for kernel data,
1200055 // segment 3 is for process 1 code,
1200056 // segment 4 is for process 1 data,
1200057 // ...
1200058 //
1200059 #define gdt_pid_to_segment_text(p) (p*2+1)
1200060 #define gdt_pid_to_segment_data(p) (p*2+2)
1200061 #define gdt_segment_text_to_pid(s) (s/2)
1200062 #define gdt_segment_data_to_pid(s) (s/2-1)
1200063 //----------------------------------------------------------
1200064 // IDT
1200065 //----------------------------------------------------------
1200066 #define IDT_ITEMS 129 // 0-128 0x00-0x80
1200067 //----------------------------------------------------------
1200068 typedef struct
1200069 {
1200070 uint32_t offset_a:16, selector:16;
1200071 uint32_t filler:8,
1200072 type:4, system:1, dpl:2, present:1, offset_b:16;
1200073 } idt_t;
1200074 //
1200075 extern idt_t idt_table[IDT_ITEMS];
1200076 //----------------------------------------------------------
1200077 typedef struct
1200078 {
1200079 uint16_t limit;
1200080 uint32_t base;
1200081 } __attribute__ ((packed)) idtr_t;
1200082 //
1200083 extern idtr_t idt_register;
1200084 //----------------------------------------------------------
1200085 void idt_descriptor (int desc, void *isr,
1200086 uint16_t selector, bool present,
1200087 char type, char dpl);
1200088 void idt_load (void *idtr);
1200089 void idt (void);
1200090 void idt_irq_remap (unsigned int offset_1,
1200091 unsigned int offset_2);
1200092 void idt_print (void *idtr, unsigned int first,
1200093 unsigned int last);
1200094 //----------------------------------------------------------
1200095 // ISR
1200096 //----------------------------------------------------------
1200097 void isr_0 (void);
1200098 void isr_1 (void);
1200099 void isr_2 (void);
1200100 void isr_3 (void);
1200101 void isr_4 (void);
1200102 void isr_5 (void);
1200103 void isr_6 (void);
1200104 void isr_7 (void);
1200105 void isr_8 (void);
1200106 void isr_9 (void);
1200107 void isr_10 (void);
1200108 void isr_11 (void);
1200109 void isr_12 (void);
1200110 void isr_13 (void);
1200111 void isr_14 (void);
1200112 void isr_15 (void);
1200113 void isr_16 (void);
1200114 void isr_17 (void);
1200115 void isr_18 (void);
1200116 void isr_19 (void);
1200117 void isr_20 (void);
1200118 void isr_21 (void);
1200119 void isr_22 (void);
1200120 void isr_23 (void);
1200121 void isr_24 (void);
1200122 void isr_25 (void);
1200123 void isr_26 (void);
1200124 void isr_27 (void);
1200125 void isr_28 (void);
1200126 void isr_29 (void);
1200127 void isr_30 (void);
1200128 void isr_31 (void);
1200129 void isr_32 (void);
1200130 void isr_33 (void);
1200131 void isr_34 (void);
1200132 void isr_35 (void);
1200133 void isr_36 (void);
1200134 void isr_37 (void);
1200135 void isr_38 (void);
1200136 void isr_39 (void);
1200137 void isr_40 (void);
1200138 void isr_41 (void);
1200139 void isr_42 (void);
1200140 void isr_43 (void);
1200141 void isr_44 (void);
1200142 void isr_45 (void);
1200143 void isr_46 (void);
1200144 void isr_47 (void);
1200145 void isr_128 (void);
1200146 //
1200147 char *isr_exception_name (int exception);
1200148 //
1200149 void isr_exception_unrecoverable (uint32_t eax,
1200150 uint32_t ecx,
1200151 uint32_t edx,
1200152 uint32_t ebx,
1200153 uint32_t ebp,
1200154 uint32_t esi,
1200155 uint32_t edi,
1200156 uint32_t ds,
1200157 uint32_t es,
1200158 uint32_t fs,
1200159 uint32_t gs,
1200160 uint32_t interrupt,
1200161 uint32_t error,
1200162 uint32_t eip,
1200163 uint32_t cs,
1200164 uint32_t eflags);
1200165 //
1200166 void isr_irq_clear (uint32_t idtn);
1200167 void isr_irq_clear_pic1 (void);
1200168 void isr_irq_clear_pic2 (void);
1200169 //----------------------------------------------------------
1200170 // I/O
1200171 //----------------------------------------------------------
1200172 uint32_t _in_8 (uint32_t port);
1200173 uint32_t _in_16 (uint32_t port);
1200174 uint32_t _in_32 (uint32_t port);
1200175 void _out_8 (uint32_t port, uint32_t value);
1200176 void _out_16 (uint32_t port, uint32_t value);
1200177 void _out_32 (uint32_t port, uint32_t value);
1200178 //
1200179 #define in_8(port) \
1200180 ((unsigned int) _in_8 ((uint32_t) port))
1200181 #define in_16(port) \
1200182 ((unsigned int) _in_16 ((uint32_t) port))
1200183 #define in_32(port) \
1200184 ((unsigned int) _in_32 ((uint32_t) port))
1200185 #define out_8(port, value) \
1200186 (_out_8 ((uint32_t) port, (uint32_t) value))
1200187 #define out_16(port, value) \
1200188 (_out_16 ((uint32_t) port, (uint32_t) value))
1200189 #define out_32(port, value) \
1200190 (_out_32 ((uint32_t) port, (uint32_t) value))
1200191 //----------------------------------------------------------
1200192 // Interrupt on/off
1200193 //----------------------------------------------------------
1200194 void cli (void);
1200195 void sti (void);
1200196 void irq_on (unsigned int irq);
1200197 void irq_off (unsigned int irq);
1200198 //----------------------------------------------------------
1200199 #endif
|
|
94.6.1
kernel/ibm_i386/_in_16.s
Si veda la sezione 93.7.
1210001 .global _in_16
1210002 #------------------------------------------------------
1210003 .section .text
1210004 #------------------------------------------------------
1210005 # Port input word.
1210006 #------------------------------------------------------
1210007 _in_16:
1210008 enter $4, $0 # 1 local variable.
1210009 pushf
1210010 pusha
1210011 .equ IN_PORT, 8 # First argument.
1210012 .equ IN_DATA, -4 # Local variable.
1210013 mov IN_PORT(%ebp), %edx # Copy the port number
1210014 # into EDX, but
1210015 # then only DX will be
1210016 # used.
1210017 mov $0, %eax # Reset EAX.
1210018 in %dx, %ax # Read DX port and
1210019 # save into AX.
1210020 mov %eax, IN_DATA(%ebp) # Save EAX inside the
1210021 # local variable.
1210022 popa
1210023 popf
1210024 mov IN_DATA(%ebp), %eax # Restore EAX and
1210025 leave # return.
1210026 ret
|
|
94.6.2
kernel/ibm_i386/_in_32.s
Si veda la sezione 93.7.
1220001 .global _in_32
1220002 #------------------------------------------------------
1220003 .section .text
1220004 #------------------------------------------------------
1220005 # Port input word.
1220006 #------------------------------------------------------
1220007 _in_32:
1220008 enter $4, $0 # 1 local variable.
1220009 pushf
1220010 pusha
1220011 .equ IN_PORT, 8 # First argument.
1220012 .equ IN_DATA, -4 # Local variable.
1220013 mov IN_PORT(%ebp), %edx # Copy the port number
1220014 # into EDX, but
1220015 # then only DX will be
1220016 # used.
1220017 mov $0, %eax # Reset EAX.
1220018 inl %dx, %eax # Read DX port and
1220019 # save into EAX.
1220020 mov %eax, IN_DATA(%ebp) # Save EAX inside the
1220021 # local variable.
1220022 popa
1220023 popf
1220024 mov IN_DATA(%ebp), %eax # Restore EAX and
1220025 leave # return.
1220026 ret
|
|
94.6.3
kernel/ibm_i386/_in_8.s
Si veda la sezione 93.7.
1230001 .global _in_8
1230002 #------------------------------------------------------
1230003 .section .text
1230004 #------------------------------------------------------
1230005 # Port input byte.
1230006 #------------------------------------------------------
1230007 _in_8:
1230008 enter $4, $0 # 1 local variable.
1230009 pushf
1230010 pusha
1230011 .equ IN_PORT, 8 # First argument.
1230012 .equ IN_DATA, -4 # Local variable.
1230013 mov IN_PORT(%ebp), %edx # Copy the port number
1230014 # into EDX, but
1230015 # then only DX will be
1230016 # used.
1230017 mov $0, %eax # Reset EAX.
1230018 inb %dx, %al # Read DX port and
1230019 # save into AL.
1230020 mov %eax, IN_DATA(%ebp) # Save EAX inside the
1230021 # local variable.
1230022 popa
1230023 popf
1230024 mov IN_DATA(%ebp), %eax # Restore EAX and
1230025 leave # return.
1230026 ret
|
|
94.6.4
kernel/ibm_i386/_out_16.s
Si veda la sezione 93.7.
1240001 .global _out_16
1240002 #------------------------------------------------------
1240003 .section .text
1240004 #------------------------------------------------------
1240005 # Port output word.
1240006 #------------------------------------------------------
1240007 _out_16:
1240008 enter $0, $0 # No local variables.
1240009 pushf
1240010 pusha
1240011 .equ OUT_PORT, 8 # First parameter.
1240012 .equ OUT_DATA, 12 # Second parameter.
1240013 mov OUT_PORT(%ebp), %edx # Copy output port to
1240014 # EDX, but only DX
1240015 # will be used.
1240016 mov OUT_DATA(%ebp), %eax # Copy output data to
1240017 # EAX, but only AX
1240018 # will be used.
1240019 out %ax, %dx # Send to the port.
1240020 popa
1240021 popf
1240022 leave
1240023 ret
|
|
94.6.5
kernel/ibm_i386/_out_32.s
Si veda la sezione 93.7.
1250001 .global _out_32
1250002 #------------------------------------------------------
1250003 .section .text
1250004 #------------------------------------------------------
1250005 # Port output word.
1250006 #------------------------------------------------------
1250007 _out_32:
1250008 enter $0, $0 # No local variables.
1250009 pushf
1250010 pusha
1250011 .equ OUT_PORT, 8 # First parameter.
1250012 .equ OUT_DATA, 12 # Second parameter.
1250013 mov OUT_PORT(%ebp), %edx # Copy output port to
1250014 # EDX, but only DX
1250015 # will be used.
1250016 mov OUT_DATA(%ebp), %eax # Copy output data to
1250017 # EAX.
1250018 outl %eax, %dx # Send to the port.
1250019 popa
1250020 popf
1250021 leave
1250022 ret
|
|
94.6.6
kernel/ibm_i386/_out_8.s
Si veda la sezione 93.7.
1260001 .global _out_8
1260002 #------------------------------------------------------
1260003 .section .text
1260004 #------------------------------------------------------
1260005 # Port output byte.
1260006 #------------------------------------------------------
1260007 _out_8:
1260008 enter $0, $0 # No local variables.
1260009 pushf
1260010 pusha
1260011 .equ OUT_PORT, 8 # First parameter.
1260012 .equ OUT_DATA, 12 # Second parameter.
1260013 mov OUT_PORT(%ebp), %edx # Copy output port to
1260014 # EDX, but only DX
1260015 # will be used.
1260016 mov OUT_DATA(%ebp), %eax # Copy output data to
1260017 # EAX, but only AL
1260018 # will be used.
1260019 outb %al, %dx # Send to the port.
1260020 popa
1260021 popf
1260022 leave
1260023 ret
|
|
94.6.7
kernel/ibm_i386/cli.s
Si veda la sezione 93.7.
1270001 .global cli
1270002 #------------------------------------------------------
1270003 .text
1270004 #------------------------------------------------------
1270005 # Clear interrupt flag.
1270006 #------------------------------------------------------
1270007 .align 4
1270008 cli:
1270009 cli
1270010 ret
|
|
94.6.8
kernel/ibm_i386/gdt.c
Si veda la sezione 93.7.
1280001 #include <kernel/ibm_i386.h>
1280002 #include <kernel/multiboot.h>
1280003 //----------------------------------------------------------
1280004 void
1280005 gdt (void)
1280006 {
1280007 uint32_t blocks; // Total available memory
1280008 // blocks.
1280009 //
1280010 // Calculate memory blocks.
1280011 //
1280012 blocks = (multiboot.mem_upper * 1024) / 4096;
1280013 //
1280014 // Set data for GDTR register.
1280015 //
1280016 gdt_register.limit = (sizeof (gdt_table) - 1);
1280017 gdt_register.base = (uint32_t) & gdt_table[0];
1280018 //
1280019 // Reset items inside `gdt_table[]'.
1280020 // gdt_table[0] must be null and is not to be
1280021 // used.
1280022 //
1280023 int i;
1280024 for (i = 0; i < GDT_ITEMS; i++)
1280025 {
1280026 gdt_segment (i, 0, 0, 0, 0, 0);
1280027 }
1280028 //
1280029 // gdt_table[1] is for kernel code.
1280030 // It covers all the available memory, with DPL 0.
1280031 // The selector is 8+0 = 0x08+0.
1280032 //
1280033 gdt_segment (1, 0, blocks, 1, 1, 0);
1280034 //
1280035 // gdt_table[2] is for kernel data, including stack
1280036 // (the stack
1280037 // MUST be in the same address space of data).
1280038 // It covers all the available memory, with DPL 0.
1280039 // The selector is 16+0 = 0x10+0.
1280040 //
1280041 gdt_segment (2, 0, blocks, 1, 0, 0);
1280042 //
1280043 // Load the GDT table.
1280044 //
1280045 gdt_load (&gdt_register);
1280046 }
|
|
94.6.9
kernel/ibm_i386/gdt_load.s
Si veda la sezione 93.7.
1290001 .globl gdt_load
1290002 #
1290003 gdt_load:
1290004 enter $0, $0
1290005 .equ gdtr_pointer, 8 # Primo argomento.
1290006 mov gdtr_pointer(%ebp), %eax # Copia il
1290007 # puntatore in EAX.
1290008 leave
1290009 #
1290010 lgdt (%eax) # Carica il registro GDTR
1290011 # dall'indirizzo in EAX.
1290012 #
1290013 # 2 kernel data, included stack, DPL 0, covering
1290014 # all the available
1290015 # memory: segment selector 0x10+0.
1290016 #
1290017 mov $16, %ax
1290018 mov %ax, %ds
1290019 mov %ax, %es
1290020 mov %ax, %fs
1290021 mov %ax, %gs
1290022 mov %ax, %ss # The stack MUST be in the same
1290023 # address space of the other
1290024 # data, to allow pointers to
1290025 # # work correctly.
1290026 #
1290027 # 2 kernel code, DPL 0, covering all the available
1290028 # memory:
1290029 # segment selector 0x08+0.
1290030 #
1290031 jmp $8, $flush
1290032 flush:
1290033 ret
|
|
94.6.10
kernel/ibm_i386/gdt_print.c
Si veda la sezione 93.7.
1300001 #include <kernel/ibm_i386.h>
1300002 #include <kernel/lib_k.h>
1300003 //
1300004 void
1300005 gdt_print (void *gdtr, unsigned int first,
1300006 unsigned int last)
1300007 {
1300008 gdtr_t *g = gdtr;
1300009 uint32_t *p = (uint32_t *) g->base;
1300010 //
1300011 int max = (g->limit + 1) / (sizeof (uint32_t));
1300012 int i;
1300013 //
1300014 if (((first * 2) > max) || (first > last))
1300015 {
1300016 return;
1300017 }
1300018 //
1300019 k_printf ("[%s] base: 0x%08" PRIX32 " limit: 0x%04"
1300020 PRIX32 "\n", __func__, g->base, g->limit);
1300021 //
1300022 for (i = (first * 2); i < max && i <= (last * 2); i += 2)
1300023 {
1300024 k_printf ("[%4" PRIx32 "] %032" PRIb32 " %032"
1300025 PRIb32 "\n", i / 2, p[i], p[i + 1]);
1300026 }
1300027 }
|
|
94.6.11
kernel/ibm_i386/gdt_public.c
Si veda la sezione 93.7.
1310001 #include <kernel/ibm_i386.h>
1310002 //----------------------------------------------------------
1310003 gdt_t gdt_table[GDT_ITEMS];
1310004 gdtr_t gdt_register;
|
|
94.6.12
kernel/ibm_i386/gdt_segment.c
Si veda la sezione 93.7.
1320001 #include <kernel/ibm_i386.h>
1320002 #include <errno.h>
1320003 //----------------------------------------------------------
1320004 int
1320005 gdt_segment (int segment,
1320006 uint32_t base,
1320007 uint32_t limit,
1320008 bool present, bool code, unsigned char dpl)
1320009 {
1320010 //
1320011 // Verify if the segment is valid.
1320012 //
1320013 if ((segment >= ((sizeof (gdt_table)) / 8))
1320014 || (segment < 0))
1320015 {
1320016 errset (EINVAL);
1320017 return (-1);
1320018 }
1320019 //
1320020 // Limit.
1320021 //
1320022 gdt_table[segment].limit_a = (limit & 0x0000FFFF);
1320023 gdt_table[segment].limit_b = limit / 0x10000;
1320024 //
1320025 // Base address.
1320026 //
1320027 gdt_table[segment].base_a = (base & 0x0000FFFF);
1320028 gdt_table[segment].base_b =
1320029 ((base / 0x10000) & 0x000000FF);
1320030 gdt_table[segment].base_c = (base / 0x1000000);
1320031 //
1320032 // Attributes.
1320033 //
1320034
1320035 //
1320036 // Internal update.
1320037 //
1320038 gdt_table[segment].accessed = 0;
1320039 //
1320040 // r, w, x.
1320041 //
1320042 gdt_table[segment].write_execute = 1;
1320043 //
1320044 // Normal and conforming.
1320045 //
1320046 gdt_table[segment].expansion_conforming = 0;
1320047 //
1320048 gdt_table[segment].code_or_data = code;
1320049 gdt_table[segment].code_data_or_system = 1;
1320050 gdt_table[segment].dpl = dpl;
1320051 gdt_table[segment].present = present;
1320052 gdt_table[segment].available = 0; // 0
1320053 gdt_table[segment].reserved = 0; // 0
1320054 gdt_table[segment].big = 1; // 32 bit
1320055 gdt_table[segment].granularity = 1; // 4 Kibyte
1320056 //
1320057 return (0);
1320058 }
|
|
94.6.13
kernel/ibm_i386/idt.c
Si veda la sezione 93.7.
1330001 #include <kernel/ibm_i386.h>
1330002 //----------------------------------------------------------
1330003 void
1330004 idt (void)
1330005 {
1330006 //
1330007 // Set necessary data for the IDTR register.
1330008 //
1330009 idt_register.limit = (sizeof (idt_table) - 1);
1330010 idt_register.base = (uint32_t) & idt_table[0];
1330011 //
1330012 // Reset all items inside the array `idt_table[]'.
1330013 //
1330014 int i;
1330015 for (i = 0; i < IDT_ITEMS; i++)
1330016 {
1330017 idt_descriptor (i, 0, 0, 0, 0, 0);
1330018 }
1330019 //
1330020 // Place hardware interrupt from IRQ 0 to IRQ 7
1330021 // starting from descriptor 32 and from IRQ 8 to
1330022 // IRQ 15 starting from descriptor 40.
1330023 //
1330024 idt_irq_remap (32, 40);
1330025 //
1330026 // Set the ISR routines to the items inside the IDT
1330027 // table.
1330028 //
1330029 idt_descriptor (0, isr_0, 0x0008, 1, 0xE, 0);
1330030 idt_descriptor (1, isr_1, 0x0008, 1, 0xE, 0);
1330031 idt_descriptor (2, isr_2, 0x0008, 1, 0xE, 0);
1330032 idt_descriptor (3, isr_3, 0x0008, 1, 0xE, 0);
1330033 idt_descriptor (4, isr_4, 0x0008, 1, 0xE, 0);
1330034 idt_descriptor (5, isr_5, 0x0008, 1, 0xE, 0);
1330035 idt_descriptor (6, isr_6, 0x0008, 1, 0xE, 0);
1330036 idt_descriptor (7, isr_7, 0x0008, 1, 0xE, 0);
1330037 idt_descriptor (8, isr_8, 0x0008, 1, 0xE, 0);
1330038 idt_descriptor (9, isr_9, 0x0008, 1, 0xE, 0);
1330039 idt_descriptor (10, isr_10, 0x0008, 1, 0xE, 0);
1330040 idt_descriptor (11, isr_11, 0x0008, 1, 0xE, 0);
1330041 idt_descriptor (12, isr_12, 0x0008, 1, 0xE, 0);
1330042 idt_descriptor (13, isr_13, 0x0008, 1, 0xE, 0);
1330043 idt_descriptor (14, isr_14, 0x0008, 1, 0xE, 0);
1330044 idt_descriptor (15, isr_15, 0x0008, 1, 0xE, 0);
1330045 idt_descriptor (16, isr_16, 0x0008, 1, 0xE, 0);
1330046 idt_descriptor (17, isr_17, 0x0008, 1, 0xE, 0);
1330047 idt_descriptor (18, isr_18, 0x0008, 1, 0xE, 0);
1330048 idt_descriptor (19, isr_19, 0x0008, 1, 0xE, 0);
1330049 idt_descriptor (20, isr_20, 0x0008, 1, 0xE, 0);
1330050 idt_descriptor (21, isr_21, 0x0008, 1, 0xE, 0);
1330051 idt_descriptor (22, isr_22, 0x0008, 1, 0xE, 0);
1330052 idt_descriptor (23, isr_23, 0x0008, 1, 0xE, 0);
1330053 idt_descriptor (24, isr_24, 0x0008, 1, 0xE, 0);
1330054 idt_descriptor (25, isr_25, 0x0008, 1, 0xE, 0);
1330055 idt_descriptor (26, isr_26, 0x0008, 1, 0xE, 0);
1330056 idt_descriptor (27, isr_27, 0x0008, 1, 0xE, 0);
1330057 idt_descriptor (28, isr_28, 0x0008, 1, 0xE, 0);
1330058 idt_descriptor (29, isr_29, 0x0008, 1, 0xE, 0);
1330059 idt_descriptor (30, isr_10, 0x0008, 1, 0xE, 0);
1330060 idt_descriptor (31, isr_31, 0x0008, 1, 0xE, 0);
1330061 idt_descriptor (32, isr_32, 0x0008, 1, 0xE, 0);
1330062 idt_descriptor (33, isr_33, 0x0008, 1, 0xE, 0);
1330063 idt_descriptor (34, isr_34, 0x0008, 1, 0xE, 0);
1330064 idt_descriptor (35, isr_35, 0x0008, 1, 0xE, 0);
1330065 idt_descriptor (36, isr_36, 0x0008, 1, 0xE, 0);
1330066 idt_descriptor (37, isr_37, 0x0008, 1, 0xE, 0);
1330067 idt_descriptor (38, isr_38, 0x0008, 1, 0xE, 0);
1330068 idt_descriptor (39, isr_39, 0x0008, 1, 0xE, 0);
1330069 idt_descriptor (40, isr_40, 0x0008, 1, 0xE, 0);
1330070 idt_descriptor (41, isr_41, 0x0008, 1, 0xE, 0);
1330071 idt_descriptor (42, isr_42, 0x0008, 1, 0xE, 0);
1330072 idt_descriptor (43, isr_43, 0x0008, 1, 0xE, 0);
1330073 idt_descriptor (44, isr_44, 0x0008, 1, 0xE, 0);
1330074 idt_descriptor (45, isr_45, 0x0008, 1, 0xE, 0);
1330075 idt_descriptor (46, isr_46, 0x0008, 1, 0xE, 0);
1330076 idt_descriptor (47, isr_47, 0x0008, 1, 0xE, 0);
1330077 //
1330078 // The following item is for the system calls.
1330079 //
1330080 idt_descriptor (128, isr_128, 0x0008, 1, 0xE, 0);
1330081 //
1330082 // Activate the IDT loading the IDTR register.
1330083 //
1330084 idt_load (&idt_register);
1330085 }
|
|
94.6.14
kernel/ibm_i386/idt_descriptor.c
Si veda la sezione 93.7.
1340001 #include <kernel/ibm_i386.h>
1340002 //----------------------------------------------------------
1340003 void
1340004 idt_descriptor (int desc,
1340005 void *isr,
1340006 uint16_t selector,
1340007 bool present, char type, char dpl)
1340008 {
1340009 uint32_t offset = (uint32_t) isr;
1340010 //
1340011 // Unset reserved bits and the system bit.
1340012 //
1340013 idt_table[desc].filler = 0;
1340014 idt_table[desc].system = 0;
1340015 //
1340016 // Relative address.
1340017 //
1340018 idt_table[desc].offset_a = (offset & 0x0000FFFF);
1340019 idt_table[desc].offset_b = (offset / 0x10000);
1340020 //
1340021 // Selector.
1340022 //
1340023 idt_table[desc].selector = selector;
1340024 //
1340025 // Valid item?
1340026 //
1340027 idt_table[desc].present = present;
1340028 //
1340029 // Type (gate type).
1340030 //
1340031 idt_table[desc].type = (type & 0x0F);
1340032 //
1340033 // DPL.
1340034 //
1340035 idt_table[desc].dpl = (dpl & 0x03);
1340036 }
|
|
94.6.15
kernel/ibm_i386/idt_irq_remap.c
Si veda la sezione 93.7.
1350001 #include <kernel/lib_k.h>
1350002 #include <kernel/ibm_i386.h>
1350003 //----------------------------------------------------------
1350004 #define DEBUG 0
1350005 //----------------------------------------------------------
1350006 void
1350007 idt_irq_remap (unsigned int offset_1, unsigned int offset_2)
1350008 {
1350009 //
1350010 // PIC_P è il PIC primario o «master»;
1350011 // PIC_S è il PIC secondario o «slave».
1350012 //
1350013 // Quando si manifesta un IRQ che riguarda il PIC
1350014 // secondario,
1350015 // il PIC primario riceve IRQ 2.
1350016 //
1350017 // ICW = initialization command word.
1350018 // OCW = operation command word.
1350019 //
1350020 if (DEBUG)
1350021 {
1350022 k_printf
1350023 ("[%s] PIC (programmable interrupt "
1350024 "controller) " "remap: ", __func__);
1350025 }
1350026 //
1350027 out_8 (0x20, 0x10 + 0x01); // Initialization:
1350028 // 0x10 means that is
1350029 out_8 (0xA0, 0x10 + 0x01); // is ICW1; 0x01 means
1350030 // that must
1350031 // continue up to ICW4.
1350032 if (DEBUG)
1350033 {
1350034 k_printf ("ICW1");
1350035 }
1350036 out_8 (0x21, offset_1); // ICW2: PIC_P
1350037 // starting at
1350038 // «offset_1».
1350039 out_8 (0xA1, offset_2); // PIC_S starting at
1350040 // «offset_2».
1350041 if (DEBUG)
1350042 {
1350043 k_printf (", ICW2");
1350044 }
1350045 out_8 (0x21, 0x04); // ICW3 PIC_P: IRQ2 driven
1350046 // from PIC_S.
1350047 out_8 (0xA1, 0x02); // ICW3 PIC_S: driving IRQ2
1350048 // from PIC_P.
1350049 if (DEBUG)
1350050 {
1350051 k_printf (", ICW3");
1350052 }
1350053 out_8 (0x21, 0x01); // ICW4: si precisa solo la
1350054 // modalità
1350055 out_8 (0xA1, 0x01); // del microprocessore; 0x01 =
1350056 // 8086.
1350057 if (DEBUG)
1350058 {
1350059 k_printf (", ICW4");
1350060 }
1350061 out_8 (0x21, 0x00); // OCW1: reset mask to enable
1350062 // all
1350063 out_8 (0xA1, 0x00); // IRQ numbers.
1350064 if (DEBUG)
1350065 {
1350066 k_printf (", OCW1.\n");
1350067 }
1350068 }
|
|
94.6.16
kernel/ibm_i386/idt_load.s
Si veda la sezione 93.7.
1360001 .globl idt_load
1360002 #
1360003 idt_load:
1360004 enter $0, $0
1360005 .equ idtr_pointer, 8 # Primo argomento.
1360006 mov idtr_pointer(%ebp), %eax # Copia il puntatore
1360007 # in EAX.
1360008 leave
1360009 #
1360010 lidt (%eax) # Utilizza la tabella IDT a cui
1360011 # punta EAX.
1360012 #
1360013 ret
|
|
94.6.17
kernel/ibm_i386/idt_print.c
Si veda la sezione 93.7.
1370001 #include <kernel/ibm_i386.h>
1370002 #include <kernel/lib_k.h>
1370003 //
1370004 void
1370005 idt_print (void *idtr, unsigned int first,
1370006 unsigned int last)
1370007 {
1370008 idtr_t *g = idtr;
1370009 uint32_t *p = (uint32_t *) g->base;
1370010 //
1370011 int max = (g->limit + 1) / (sizeof (uint32_t));
1370012 int i;
1370013 //
1370014 if (((first * 2) > max) || (first > last))
1370015 {
1370016 return;
1370017 }
1370018 //
1370019 k_printf ("[%s] base: 0x%08" PRIX32 " limit: 0x%04"
1370020 PRIX32 "\n", __func__, g->base, g->limit);
1370021 //
1370022 for (i = (first * 2); i < max && i <= (last * 2); i += 2)
1370023 {
1370024 k_printf ("[%4" PRIx32 "] %032" PRIb32 " %032"
1370025 PRIb32 "\n", i / 2, p[i], p[i + 1]);
1370026 }
1370027 }
|
|
94.6.18
kernel/ibm_i386/idt_public.c
Si veda la sezione 93.7.
1380001 #include <kernel/ibm_i386.h>
1380002 //----------------------------------------------------------
1380003 idt_t idt_table[129];
1380004 idtr_t idt_register;
|
|
94.6.19
kernel/ibm_i386/irq_off.c
Si veda la sezione 93.7.
1390001 #include <kernel/ibm_i386.h>
1390002 #include <stdint.h>
1390003 //----------------------------------------------------------
1390004 void
1390005 irq_off (unsigned int irq)
1390006 {
1390007 uint32_t mask;
1390008 uint32_t status;
1390009 //
1390010 if (irq > 15)
1390011 {
1390012 return; // There is not such IRQ.
1390013 }
1390014 else
1390015 {
1390016 mask = ((uint32_t) 1 << irq);
1390017 //
1390018 // IRQ from 0 to 7.
1390019 //
1390020 status = in_8 ((uint32_t) 0x21);
1390021 status = status | mask;
1390022 out_8 ((uint32_t) 0x21, status);
1390023 //
1390024 // IRQ from 8 to 15.
1390025 //
1390026 status = in_8 ((uint32_t) 0xA1);
1390027 status = status | (mask >> 8);
1390028 out_8 ((uint32_t) 0xA1, status);
1390029 }
1390030 }
|
|
94.6.20
kernel/ibm_i386/irq_on.c
Si veda la sezione 93.7.
1400001 #include <kernel/ibm_i386.h>
1400002 #include <stdint.h>
1400003 //----------------------------------------------------------
1400004 void
1400005 irq_on (unsigned int irq)
1400006 {
1400007 uint32_t mask;
1400008 uint32_t status;
1400009 //
1400010 if (irq > 15)
1400011 {
1400012 return; // There is not such IRQ.
1400013 }
1400014 else
1400015 {
1400016 mask = ~((uint32_t) 1 << irq);
1400017 //
1400018 // IRQ from 0 to 7.
1400019 //
1400020 status = in_8 ((uint32_t) 0x21);
1400021 status = status & mask;
1400022 out_8 ((uint32_t) 0x21, status);
1400023 //
1400024 // IRQ from 8 to 15.
1400025 //
1400026 status = in_8 ((uint32_t) 0xA1);
1400027 status = status & (mask >> 8);
1400028 out_8 ((uint32_t) 0xA1, status);
1400029 }
1400030 }
|
|
94.6.21
kernel/ibm_i386/isr.s
Si veda la sezione 93.7.
1410001 .extern isr_exception_unrecoverable
1410002 .extern isr_irq_clear
1410003 .extern isr_irq_clear_pic1
1410004 .extern isr_irq_clear_pic2
1410005 .extern kbd_isr
1410006 .extern sysroutine
1410007 .extern proc_current
1410008 .extern proc_stack_segment_selector;
1410009 .extern proc_stack_pointer
1410010 .extern proc_scheduler
1410011 #.extern proc_sch_terminals
1410012 #
1410013 .global _clock_kernel
1410014 .global _clock_time
1410015 .global _ksp
1410016 #
1410017 .global isr_0
1410018 .global isr_1
1410019 .global isr_2
1410020 .global isr_3
1410021 .global isr_4
1410022 .global isr_5
1410023 .global isr_6
1410024 .global isr_7
1410025 .global isr_8
1410026 .global isr_9
1410027 .global isr_10
1410028 .global isr_11
1410029 .global isr_12
1410030 .global isr_13
1410031 .global isr_14
1410032 .global isr_15
1410033 .global isr_16
1410034 .global isr_17
1410035 .global isr_18
1410036 .global isr_19
1410037 .global isr_20
1410038 .global isr_21
1410039 .global isr_22
1410040 .global isr_23
1410041 .global isr_24
1410042 .global isr_25
1410043 .global isr_26
1410044 .global isr_27
1410045 .global isr_28
1410046 .global isr_29
1410047 .global isr_30
1410048 .global isr_31
1410049 .global isr_32
1410050 .global isr_33
1410051 .global isr_34
1410052 .global isr_35
1410053 .global isr_36
1410054 .global isr_37
1410055 .global isr_38
1410056 .global isr_39
1410057 .global isr_40
1410058 .global isr_41
1410059 .global isr_42
1410060 .global isr_43
1410061 .global isr_44
1410062 .global isr_45
1410063 .global isr_46
1410064 .global isr_47
1410065 .global isr_128
1410066 #------------------------------------------------------
1410067 .section .data
1410068 #------------------------------------------------------
1410069 proc_syscallnr: .int 0x00000000
1410070 proc_msg_offset: .int 0x00000000
1410071 proc_msg_size: .int 0x00000000
1410072 proc_instruction_pointer: .int 0x00000000
1410073 proc_back_address: .int 0x00000000
1410074 _ksp: .int 0x00000000
1410075 syscall_working: .int 0x00000000
1410076 _clock_kernel:
1410077 kticks_lo: .int 0x00000000
1410078 kticks_hi: .int 0x00000000
1410079 _clock_time:
1410080 tticks_lo: .int 0x00000000
1410081 tticks_hi: .int 0x00000000
1410082 #------------------------------------------------------
1410083 .section .text
1410084 #------------------------------------------------------
1410085 #
1410086 # Inside the stack there is already, placed by the CPU:
1410087 # [omissis]
1410088 # push %eflags
1410089 # push %cs
1410090 # push %eip
1410091 #
1410092 #------------------------------------------------------
1410093 isr_0: # «division by zero exception»
1410094 cli
1410095 push $0 # Null error code.
1410096 push $0 # Exception number.
1410097 jmp exception_unrecoverable
1410098 #------------------------------------------------------
1410099 isr_1: # «debug exception»
1410100 cli
1410101 push $0 # Null error code.
1410102 push $1 # Exception number.
1410103 jmp exception_unrecoverable
1410104 #------------------------------------------------------
1410105 isr_2: # «non maskable interrupt exception»
1410106 cli
1410107 push $0 # Null error code.
1410108 push $2 # Exception number.
1410109 jmp exception_unrecoverable
1410110 #------------------------------------------------------
1410111 isr_3: # «breakpoint exception»
1410112 cli
1410113 push $0 # Null error code.
1410114 push $3 # Exception number.
1410115 jmp exception_unrecoverable
1410116 #------------------------------------------------------
1410117 isr_4: # «into detected overflow exception»
1410118 cli
1410119 push $0 # Null error code.
1410120 push $4 # Exception number.
1410121 jmp exception_unrecoverable
1410122 #------------------------------------------------------
1410123 isr_5: # «out of bounds exception»
1410124 cli
1410125 push $0 # Null error code.
1410126 push $5 # Exception number.
1410127 jmp exception_unrecoverable
1410128 #------------------------------------------------------
1410129 isr_6: # «invalid opcode exception»
1410130 cli
1410131 push $0 # Null error code.
1410132 push $6 # Exception number.
1410133 jmp exception_unrecoverable
1410134 #------------------------------------------------------
1410135 isr_7: # «no coprocessor exception»
1410136 cli
1410137 push $0 # Null error code.
1410138 push $7 # Exception number.
1410139 jmp exception_unrecoverable
1410140 #------------------------------------------------------
1410141 isr_8: # «double fault exception»
1410142 cli
1410143 # # Error code already present.
1410144 push $8 # Exception number.
1410145 jmp exception_unrecoverable
1410146 #------------------------------------------------------
1410147 isr_9: # «coprocessor segment overrun
1410148 # exception»
1410149 cli
1410150 push $0 # Null error code.
1410151 push $9 # Exception number.
1410152 jmp exception_unrecoverable
1410153 #------------------------------------------------------
1410154 isr_10: # «bad TSS exception»
1410155 cli
1410156 # # Error code already present.
1410157 push $10 # Exception number.
1410158 jmp exception_unrecoverable
1410159 #------------------------------------------------------
1410160 isr_11: # «segment not present exception»
1410161 cli
1410162 # # Error code already present.
1410163 push $11 # Exception number.
1410164 jmp exception_unrecoverable
1410165 #------------------------------------------------------
1410166 isr_12: # «stack fault exception»
1410167 cli
1410168 # # Error code already present.
1410169 push $12 # Exception number.
1410170 jmp exception_unrecoverable
1410171 #------------------------------------------------------
1410172 isr_13: # «general protection fault exception»
1410173 cli
1410174 # # Error code already present.
1410175 push $13 # Exception number.
1410176 jmp exception_unrecoverable
1410177 #------------------------------------------------------
1410178 isr_14: # «page fault exception»
1410179 cli
1410180 # # Error code already present.
1410181 push $14 # Exception number.
1410182 jmp exception_unrecoverable
1410183 #------------------------------------------------------
1410184 isr_15: # «unknown interrupt exception»
1410185 cli
1410186 push $0 # Null error code.
1410187 push $15 # Exception number.
1410188 jmp exception_unrecoverable
1410189 #------------------------------------------------------
1410190 isr_16: # «coprocessor fault exception»
1410191 cli
1410192 push $0 # Null error code.
1410193 push $16 # Exception number.
1410194 jmp exception_unrecoverable
1410195 #------------------------------------------------------
1410196 isr_17: # «alignment check exception»
1410197 cli
1410198 push $0 # Null error code.
1410199 push $17 # Exception number.
1410200 jmp exception_unrecoverable
1410201 #------------------------------------------------------
1410202 isr_18: # «machine check exception»
1410203 cli
1410204 push $0 # Null error code.
1410205 push $18 # Exception number.
1410206 jmp exception_unrecoverable
1410207 #------------------------------------------------------
1410208 isr_19: # «reserved exception»
1410209 cli
1410210 push $0 # Null error code.
1410211 push $19 # Exception number.
1410212 jmp exception_unrecoverable
1410213 #------------------------------------------------------
1410214 isr_20: # «reserved exception»
1410215 cli
1410216 push $0 # Null error code.
1410217 push $20 # Exception number.
1410218 jmp exception_unrecoverable
1410219 #------------------------------------------------------
1410220 isr_21: # «reserved exception»
1410221 cli
1410222 push $0 # Null error code.
1410223 push $21 # Exception number.
1410224 jmp exception_unrecoverable
1410225 #------------------------------------------------------
1410226 isr_22: # «reserved exception»
1410227 cli
1410228 push $0 # Null error code.
1410229 push $22 # Exception number.
1410230 jmp exception_unrecoverable
1410231 #------------------------------------------------------
1410232 isr_23: # «reserved exception»
1410233 cli
1410234 push $0 # Null error code.
1410235 push $23 # Exception number.
1410236 jmp exception_unrecoverable
1410237 #------------------------------------------------------
1410238 isr_24: # «reserved exception»
1410239 cli
1410240 push $0 # Null error code.
1410241 push $24 # Exception number.
1410242 jmp exception_unrecoverable
1410243 #------------------------------------------------------
1410244 isr_25: # «reserved exception»
1410245 cli
1410246 push $0 # Null error code.
1410247 push $25 # Exception number.
1410248 jmp exception_unrecoverable
1410249 #------------------------------------------------------
1410250 isr_26: # «reserved exception»
1410251 cli
1410252 push $0 # Null error code.
1410253 push $26 # Exception number.
1410254 jmp exception_unrecoverable
1410255 #------------------------------------------------------
1410256 isr_27: # «reserved exception»
1410257 cli
1410258 push $0 # Null error code.
1410259 push $27 # Exception number.
1410260 jmp exception_unrecoverable
1410261 #------------------------------------------------------
1410262 isr_28: # «reserved exception»
1410263 cli
1410264 push $0 # Null error code.
1410265 push $28 # Exception number.
1410266 jmp exception_unrecoverable
1410267 #------------------------------------------------------
1410268 isr_29: # «reserved exception»
1410269 cli
1410270 push $0 # Null error code.
1410271 push $29 # Exception number.
1410272 jmp exception_unrecoverable
1410273 #------------------------------------------------------
1410274 isr_30: # «reserved exception»
1410275 cli
1410276 push $0 # Null error code.
1410277 push $30 # Exception number.
1410278 jmp exception_unrecoverable
1410279 #------------------------------------------------------
1410280 isr_31: # «reserved exception»
1410281 cli
1410282 push $0 # Null error code.
1410283 push $31 # Exception number.
1410284 jmp exception_unrecoverable
1410285 #------------------------------------------------------
1410286 isr_32: # IRQ 0: «timer»
1410287 cli
1410288 jmp irq_timer
1410289 #------------------------------------------------------
1410290 isr_33: # IRQ 1: tastiera
1410291 cli
1410292 jmp irq_keyboard
1410293 #------------------------------------------------------
1410294 isr_34: # IRQ 2: it is fired for IRQ 8 to 15.
1410295 cli
1410296 #
1410297 # IRQ 2 must be ON inside the file
1410298 # `kernel/proc/proc_init.c', so
1410299 # that it is guaranteed that the PIC 1 is reset
1410300 # here.
1410301 #
1410302 call isr_irq_clear_pic1
1410303 #
1410304 # For IRQ 2 there is nothing else to do, because it
1410305 # is a link to the PIC 2 (IRQ 8 to 15).
1410306 #
1410307 iret
1410308 #------------------------------------------------------
1410309 isr_35: # IRQ 3
1410310 cli
1410311 jmp irq_pic1
1410312 #------------------------------------------------------
1410313 isr_36: # IRQ 4
1410314 cli
1410315 jmp irq_pic1
1410316 #------------------------------------------------------
1410317 isr_37: # IRQ 5
1410318 cli
1410319 jmp irq_pic1
1410320 #------------------------------------------------------
1410321 isr_38: # IRQ 6: floppy disk drive
1410322 cli
1410323 jmp irq_pic1
1410324 #------------------------------------------------------
1410325 isr_39: # IRQ 7: LPT 1
1410326 cli
1410327 jmp irq_pic1
1410328 #------------------------------------------------------
1410329 isr_40: # IRQ 8: «real time clock (RTC)»
1410330 cli
1410331 jmp irq_pic2
1410332 #------------------------------------------------------
1410333 isr_41: # IRQ 9
1410334 cli
1410335 jmp irq_pic2
1410336 #------------------------------------------------------
1410337 isr_42: # IRQ 10
1410338 cli
1410339 jmp irq_pic2
1410340 #------------------------------------------------------
1410341 isr_43: # IRQ 11
1410342 cli
1410343 jmp irq_pic2
1410344 #------------------------------------------------------
1410345 isr_44: # IRQ 12: mouse PS/2
1410346 cli
1410347 jmp irq_pic2
1410348 #------------------------------------------------------
1410349 isr_45: # IRQ 13: math coprocessor
1410350 cli
1410351 jmp irq_pic2
1410352 #------------------------------------------------------
1410353 isr_46: # IRQ 14: primary IDE channel
1410354 cli
1410355 jmp irq_pic2
1410356 #------------------------------------------------------
1410357 isr_47: # IRQ 15: secondary IDE channel
1410358 cli
1410359 jmp irq_pic2
1410360 #------------------------------------------------------
1410361 #
1410362 # Unrecoverable exceptions.
1410363 #
1410364 exception_unrecoverable:
1410365 #
1410366 # Previous pushes:
1410367 # [omissis]
1410368 # push %eflags
1410369 # push %cs
1410370 # push %eip
1410371 #
1410372 # push $<error_number>
1410373 # push $<idt_item_number>
1410374 #
1410375 pushl %gs
1410376 pushl %fs
1410377 pushl %es
1410378 pushl %ds
1410379 pushl %edi
1410380 pushl %esi
1410381 pushl %ebp
1410382 pushl %ebx
1410383 pushl %edx
1410384 pushl %ecx
1410385 pushl %eax
1410386 #
1410387 call isr_exception_unrecoverable
1410388 #
1410389 popl %eax
1410390 popl %ecx
1410391 popl %edx
1410392 popl %ebx
1410393 popl %ebp
1410394 popl %esi
1410395 popl %edi
1410396 popl %ds
1410397 popl %es
1410398 popl %fs
1410399 popl %gs
1410400 #
1410401 # Remove the IDT item number and the error code.
1410402 #
1410403 add $4, %esp
1410404 add $4, %esp
1410405 #
1410406 # Return from interrupt.
1410407 #
1410408 iret
1410409 #------------------------------------------------------
1410410 #
1410411 # Unspecified IRQ. Currently unused.
1410412 #
1410413 irq:
1410414 #
1410415 # Previous pushes:
1410416 # [omissis]
1410417 # push %eflags
1410418 # push %cs
1410419 # push %eip
1410420 #
1410421 # push $0
1410422 # push $<idt_item_number>
1410423 #
1410424 call isr_irq_clear
1410425 #
1410426 # Remove the IDT item number and the null error
1410427 # code.
1410428 #
1410429 add $4, %esp
1410430 add $4, %esp
1410431 #
1410432 # Return from interrupt.
1410433 #
1410434 iret
1410435 #------------------------------------------------------
1410436 #
1410437 # Keyboard IRQ.
1410438 #
1410439 irq_keyboard:
1410440 #
1410441 # Previous pushes:
1410442 # [omissis]
1410443 # push %eflags
1410444 # push %cs
1410445 # push %eip
1410446 #
1410447 pushl %gs
1410448 pushl %fs
1410449 pushl %es
1410450 pushl %ds
1410451 pushl %edi
1410452 pushl %esi
1410453 pushl %ebp
1410454 pushl %ebx
1410455 pushl %edx
1410456 pushl %ecx
1410457 pushl %eax
1410458 #
1410459 # Set the data segments to the kernel data segment,
1410460 # so that the following variables can be accessed.
1410461 #
1410462 mov $16, %ax # DS, ES, FS and GS.
1410463 mov %ax, %ds
1410464 mov %ax, %es
1410465 mov %ax, %fs
1410466 mov %ax, %gs
1410467 #
1410468 # Check if a system call is already working: if so,
1410469 # just leave (go to L1).
1410470 #
1410471 cmpl $1, syscall_working
1410472 je L1
1410473 #
1410474 # Call the keyboard handler.
1410475 #
1410476 call kbd_isr
1410477 #
1410478 L1: # Restore original registers and return.
1410479 #
1410480 jmp irq_pic1_pop_iret
1410481 #------------------------------------------------------
1410482 #
1410483 # Generic IRQ from PIC 1
1410484 #
1410485 irq_pic1:
1410486 #
1410487 # Previous pushes:
1410488 # [omissis]
1410489 # push %eflags
1410490 # push %cs
1410491 # push %eip
1410492 #
1410493 pushl %gs
1410494 pushl %fs
1410495 pushl %es
1410496 pushl %ds
1410497 pushl %edi
1410498 pushl %esi
1410499 pushl %ebp
1410500 pushl %ebx
1410501 pushl %edx
1410502 pushl %ecx
1410503 pushl %eax
1410504 #
1410505 # Set the data segments to the kernel data segment,
1410506 # so that the following variables can be accessed.
1410507 #
1410508 mov $16, %ax # DS, ES, FS and GS.
1410509 mov %ax, %ds
1410510 mov %ax, %es
1410511 mov %ax, %fs
1410512 mov %ax, %gs
1410513 #
1410514 # Check if a system call is already working: if so,
1410515 # just leave (go to L2).
1410516 #
1410517 cmpl $1, syscall_working
1410518 je L2
1410519 #
1410520 # If we are here, no system call is working and a
1410521 # user process was interrupted.
1410522 # Save process stack registers into kernel data
1410523 # segment.
1410524 #
1410525 mov %ss, proc_stack_segment_selector
1410526 mov %esp, proc_stack_pointer
1410527 #
1410528 # Check if it is already in kernel mode: the kernel
1410529 # has PID 0.
1410530 # If so, just leave (go to L2).
1410531 #
1410532 mov proc_current, %edx # Interrupted PID.
1410533 mov $0, %eax # Kernel PID.
1410534 cmp %eax, %edx
1410535 je L5
1410536 #
1410537 # If we are here, a user process was interrupted.
1410538 # Switch to the kernel stack (data segment
1410539 # descriptor).
1410540 #
1410541 mov $16, %ax
1410542 mov %ax, %ss
1410543 mov _ksp, %esp
1410544 #
1410545 # Call the scheduler.
1410546 #
1410547 call proc_scheduler
1410548 #
1410549 # Restore process stack registers from kernel data
1410550 # segment.
1410551 #
1410552 mov proc_stack_segment_selector, %ss
1410553 mov proc_stack_pointer, %esp
1410554 #
1410555 L5: # Restore from process stack and return.
1410556 #
1410557 jmp irq_pic1_pop_iret
1410558 #------------------------------------------------------
1410559 #
1410560 # Generic IRQ from PIC 2
1410561 #
1410562 irq_pic2:
1410563 #
1410564 # Previous pushes:
1410565 # [omissis]
1410566 # push %eflags
1410567 # push %cs
1410568 # push %eip
1410569 #
1410570 pushl %gs
1410571 pushl %fs
1410572 pushl %es
1410573 pushl %ds
1410574 pushl %edi
1410575 pushl %esi
1410576 pushl %ebp
1410577 pushl %ebx
1410578 pushl %edx
1410579 pushl %ecx
1410580 pushl %eax
1410581 #
1410582 # Set the data segments to the kernel data segment,
1410583 # so that the following variables can be accessed.
1410584 #
1410585 mov $16, %ax # DS, ES, FS and GS.
1410586 mov %ax, %ds
1410587 mov %ax, %es
1410588 mov %ax, %fs
1410589 mov %ax, %gs
1410590 #
1410591 # Check if a system call is already working: if so,
1410592 # just leave (go to L2).
1410593 #
1410594 cmpl $1, syscall_working
1410595 je L2
1410596 #
1410597 # If we are here, no system call is working and a
1410598 # user process was interrupted.
1410599 # Save process stack registers into kernel data
1410600 # segment.
1410601 #
1410602 mov %ss, proc_stack_segment_selector
1410603 mov %esp, proc_stack_pointer
1410604 #
1410605 # Check if it is already in kernel mode: the kernel
1410606 # has PID 0.
1410607 # If so, just leave (go to L2).
1410608 #
1410609 mov proc_current, %edx # Interrupted PID.
1410610 mov $0, %eax # Kernel PID.
1410611 cmp %eax, %edx
1410612 je L4
1410613 #
1410614 # If we are here, a user process was interrupted.
1410615 # Switch to the kernel stack (data segment
1410616 # descriptor).
1410617 #
1410618 mov $16, %ax
1410619 mov %ax, %ss
1410620 mov _ksp, %esp
1410621 #
1410622 # Call the scheduler.
1410623 #
1410624 call proc_scheduler
1410625 #
1410626 # Restore process stack registers from kernel data
1410627 # segment.
1410628 #
1410629 mov proc_stack_segment_selector, %ss
1410630 mov proc_stack_pointer, %esp
1410631 #
1410632 L4: # Restore from process stack and return.
1410633 #
1410634 jmp irq_pic2_pop_iret
1410635 #------------------------------------------------------
1410636 #
1410637 # Timer IRQ.
1410638 #
1410639 irq_timer:
1410640 #
1410641 # Previous pushes:
1410642 # [omissis]
1410643 # push %eflags
1410644 # push %cs
1410645 # push %eip
1410646 #
1410647 pushl %gs
1410648 pushl %fs
1410649 pushl %es
1410650 pushl %ds
1410651 pushl %edi
1410652 pushl %esi
1410653 pushl %ebp
1410654 pushl %ebx
1410655 pushl %edx
1410656 pushl %ecx
1410657 pushl %eax
1410658 #
1410659 # Set the data segments to the kernel data segment,
1410660 # so that the following variables can be accessed.
1410661 #
1410662 mov $16, %ax # DS, ES, FS and GS.
1410663 mov %ax, %ds
1410664 mov %ax, %es
1410665 mov %ax, %fs
1410666 mov %ax, %gs
1410667 #
1410668 # Increment time counters, to keep time.
1410669 #
1410670 add $1, kticks_lo # Kernel ticks counter.
1410671 adc $0, kticks_hi #
1410672 #
1410673 add $1, tticks_lo # Clock ticks counter.
1410674 adc $0, tticks_hi #
1410675 #
1410676 # Check if a system call is already working: if so,
1410677 # just leave (go to L2).
1410678 #
1410679 cmpl $1, syscall_working
1410680 je L2
1410681 #
1410682 # If we are here, no system call is working and a
1410683 # user process was interrupted.
1410684 # Save process stack registers into kernel data
1410685 # segment.
1410686 #
1410687 mov %ss, proc_stack_segment_selector
1410688 mov %esp, proc_stack_pointer
1410689 #
1410690 # Check if it is already in kernel mode: the kernel
1410691 # has PID 0.
1410692 # If so, just leave (go to L2).
1410693 #
1410694 mov proc_current, %edx # Interrupted PID.
1410695 mov $0, %eax # Kernel PID.
1410696 cmp %eax, %edx
1410697 je L2
1410698 #
1410699 # If we are here, a user process was interrupted.
1410700 # Switch to the kernel stack (data segment
1410701 # descriptor).
1410702 #
1410703 mov $16, %ax
1410704 mov %ax, %ss
1410705 mov _ksp, %esp
1410706 #
1410707 # Call the scheduler.
1410708 #
1410709 call proc_scheduler
1410710 #
1410711 # Restore process stack registers from kernel data
1410712 # segment.
1410713 #
1410714 mov proc_stack_segment_selector, %ss
1410715 mov proc_stack_pointer, %esp
1410716 #
1410717 L2: # Restore from process stack and return.
1410718 #
1410719 jmp irq_pic1_pop_iret
1410720 #------------------------------------------------------
1410721 irq_pic1_pop_iret:
1410722 #
1410723 # Restore from process stack.
1410724 #
1410725 popl %eax
1410726 popl %ecx
1410727 popl %edx
1410728 popl %ebx
1410729 popl %ebp
1410730 popl %esi
1410731 popl %edi
1410732 popl %ds
1410733 popl %es
1410734 popl %fs
1410735 popl %gs
1410736 #
1410737 # End of hardware interrupt to PIC 1.
1410738 #
1410739 call isr_irq_clear_pic1
1410740 #
1410741 # Return from interrupt.
1410742 #
1410743 iret
1410744 #------------------------------------------------------
1410745 irq_pic2_pop_iret:
1410746 #
1410747 # Restore from process stack.
1410748 #
1410749 popl %eax
1410750 popl %ecx
1410751 popl %edx
1410752 popl %ebx
1410753 popl %ebp
1410754 popl %esi
1410755 popl %edi
1410756 popl %ds
1410757 popl %es
1410758 popl %fs
1410759 popl %gs
1410760 #
1410761 # End of hardware interrupt to PIC 2 and PIC1.
1410762 #
1410763 call isr_irq_clear_pic2
1410764 #
1410765 # Return from interrupt.
1410766 #
1410767 iret
1410768 #------------------------------------------------------
1410769 #
1410770 # System call.
1410771 #
1410772 isr_128:
1410773 #
1410774 # Previous pushes:
1410775 # [omissis]
1410776 # push message_size
1410777 # push &message_structure
1410778 # push syscall_number
1410779 # push back_address # made by a call to sys()
1410780 # push %eflags # made by int $128 (0x80)
1410781 # push %cs # made by int $128 (0x80)
1410782 # push %eip # made by int $128 (0x80)
1410783 #
1410784 #--------------------------------------------------
1410785 #
1410786 # Save into process stack:
1410787 #
1410788 pushl %gs
1410789 pushl %fs
1410790 pushl %es
1410791 pushl %ds
1410792 pushl %edi
1410793 pushl %esi
1410794 pushl %ebp
1410795 pushl %ebx
1410796 pushl %edx
1410797 pushl %ecx
1410798 pushl %eax
1410799 #
1410800 # Set the data segments to the kernel data segment.
1410801 #
1410802 mov $16, %ax # DS, ES, FS and GS.
1410803 mov %ax, %ds
1410804 mov %ax, %es
1410805 mov %ax, %fs
1410806 mov %ax, %gs
1410807 #
1410808 # Tell that it is a system call.
1410809 #
1410810 movl $1, syscall_working
1410811 #
1410812 # Save process stack registers into kernel data
1410813 # segment.
1410814 #
1410815 mov %ss, proc_stack_segment_selector
1410816 mov %esp, proc_stack_pointer
1410817 #
1410818 # Save some more data, from the system call.
1410819 #
1410820 .equ SYSCALL_NUMBER, 60
1410821 .equ MESSAGE_OFFSET, 64
1410822 .equ MESSAGE_SIZE, 68
1410823 #
1410824 mov %esp, %ebp
1410825 mov SYSCALL_NUMBER(%ebp), %eax
1410826 mov %eax, proc_syscallnr
1410827 mov MESSAGE_OFFSET(%ebp), %eax
1410828 mov %eax, proc_msg_offset
1410829 mov MESSAGE_SIZE(%ebp), %eax
1410830 mov %eax, proc_msg_size
1410831 #
1410832 # Check if it is already in kernel mode: the kernel
1410833 # has PID 0.
1410834 #
1410835 mov proc_current, %edx # Interrupted PID.
1410836 mov $0, %eax # Kernel PID.
1410837 cmp %eax, %edx
1410838 jne L3
1410839 #
1410840 # It is already the kernel stack, so, the variable
1410841 # "_ksp" is aligned to current stack pointer.
1410842 # This way, the first syscall
1410843 # can work without having to set the "_ksp"
1410844 # variable to some reasonable value.
1410845 #
1410846 mov %esp, _ksp
1410847 #
1410848 L3: # Switch to the kernel stack (data segment
1410849 # descriptor).
1410850 #
1410851 mov $16, %ax
1410852 mov %ax, %ss
1410853 mov _ksp, %esp
1410854 #
1410855 # Call the external sysroutine handler.
1410856 #
1410857 push proc_msg_size
1410858 push proc_msg_offset
1410859 push proc_syscallnr
1410860 call sysroutine
1410861 add $4, %esp
1410862 add $4, %esp
1410863 add $4, %esp
1410864 #
1410865 # Restore process stack registers from kernel data
1410866 # segment.
1410867 #
1410868 mov proc_stack_segment_selector, %ss
1410869 mov proc_stack_pointer, %esp
1410870 #
1410871 # End of system call.
1410872 #
1410873 movl $0, syscall_working
1410874 #
1410875 # Restore from process stack.
1410876 #
1410877 popl %eax
1410878 popl %ecx
1410879 popl %edx
1410880 popl %ebx
1410881 popl %ebp
1410882 popl %esi
1410883 popl %edi
1410884 popl %ds
1410885 popl %es
1410886 popl %fs
1410887 popl %gs
1410888 #
1410889 # Return from interrupt.
1410890 #
1410891 iret
1410892 #------------------------------------------------------
|
|
94.6.22
kernel/ibm_i386/isr_exception_name.c
Si veda la sezione 93.7.
1420001 #include <kernel/ibm_i386.h>
1420002 //----------------------------------------------------------
1420003 char *
1420004 isr_exception_name (int exception)
1420005 {
1420006 char *description[19] = { "division by zero",
1420007 "debug",
1420008 "non maskable interrupt",
1420009 "breakpoint",
1420010 "into detected overflow",
1420011 "out of bounds",
1420012 "invalid opcode",
1420013 "no coprocessor",
1420014 "double fault",
1420015 "coprocessor segmento overrun",
1420016 "bad TSS",
1420017 "segment not present",
1420018 "stack fault",
1420019 "general protection fault",
1420020 "page fault",
1420021 "unknown interrupt",
1420022 "coprocessor fault",
1420023 "alignment check",
1420024 "machine check"
1420025 };
1420026 //
1420027 if (exception >= 0 && exception <= 18)
1420028 {
1420029 return description[exception];
1420030 }
1420031 else
1420032 {
1420033 return "unknown";
1420034 }
1420035 }
|
|
94.6.23
kernel/ibm_i386/isr_exception_unrecoverable.c
Si veda la sezione 93.7.
1430001 #include <kernel/ibm_i386.h>
1430002 #include <kernel/lib_k.h>
1430003 #include <sys/types.h>
1430004 //----------------------------------------------------------
1430005 void
1430006 isr_exception_unrecoverable (uint32_t eax,
1430007 uint32_t ecx,
1430008 uint32_t edx,
1430009 uint32_t ebx,
1430010 uint32_t ebp,
1430011 uint32_t esi,
1430012 uint32_t edi, uint32_t ds,
1430013 uint32_t es, uint32_t fs,
1430014 uint32_t gs,
1430015 uint32_t interrupt,
1430016 uint32_t error,
1430017 uint32_t eip, uint32_t cs,
1430018 uint32_t eflags)
1430019 {
1430020 pid_t pid = cs / 8;
1430021 //
1430022 k_printf
1430023 ("[%s] ERROR: pid: %i exception %i: \"%s\"\n",
1430024 __func__, pid, interrupt,
1430025 isr_exception_name (interrupt));
1430026 //
1430027 // Exit the unrecoverable application.
1430028 //
1430029 k_exit ();
1430030 }
|
|
94.6.24
kernel/ibm_i386/isr_irq_clear.c
Si veda la sezione 93.7.
1440001 #include <kernel/ibm_i386.h>
1440002 //----------------------------------------------------------
1440003 void
1440004 isr_irq_clear (uint32_t idtn)
1440005 {
1440006 int irq = idtn - 32;
1440007 //
1440008 // Must tell the PIC (programmable interrupt
1440009 // controller).
1440010 //
1440011 // If the IRQ number is between 8 and 15, send
1440012 // message «EOI»
1440013 // (End of IRQ) to PIC 2.
1440014 //
1440015 if (irq >= 8)
1440016 {
1440017 out_8 (0xA0, 0x20);
1440018 }
1440019 //
1440020 // Then send message «EOI» to PIC 1.
1440021 //
1440022 out_8 (0x20, 0x20);
1440023 }
|
|
94.6.25
kernel/ibm_i386/isr_irq_clear_pic1.c
Si veda la sezione 93.7.
1450001 #include <kernel/ibm_i386.h>
1450002 //----------------------------------------------------------
1450003 void
1450004 isr_irq_clear_pic1 (void)
1450005 {
1450006 //
1450007 // Send message «EOI» to PIC 1.
1450008 //
1450009 out_8 ((uint32_t) 0x20, (uint32_t) 0x20);
1450010 }
|
|
94.6.26
kernel/ibm_i386/isr_irq_clear_pic2.c
Si veda la sezione 93.7.
1460001 #include <kernel/ibm_i386.h>
1460002 //----------------------------------------------------------
1460003 void
1460004 isr_irq_clear_pic2 (void)
1460005 {
1460006 //
1460007 // Send message «EOI» (End of IRQ) to PIC 2.
1460008 // It must be sent after a IRQ number between 8 and
1460009 // 15, but after
1460010 // that, remember that also the PIC 1 must receive
1460011 // an «EOI» message
1460012 // (maybe with the help of `isr_irq_clear_pic1()'
1460013 // function).
1460014 //
1460015 out_8 ((uint32_t) 0xA0, (uint32_t) 0x20);
1460016 }
|
|
94.6.27
kernel/ibm_i386/sti.s
Si veda la sezione 93.7.
1470001 .global sti
1470002 #------------------------------------------------------
1470003 .text
1470004 #------------------------------------------------------
1470005 # Set interrupt flag.
1470006 #------------------------------------------------------
1470007 .align 4
1470008 sti:
1470009 sti
1470010 ret
|
|
94.7
os32: «kernel/lib_k.h»
Si veda la sezione 93.11.
1480001 #ifndef _KERNEL_LIB_K_H
1480002 #define _KERNEL_LIB_K_H 1
1480003 //----------------------------------------------------------
1480004 #include <restrict.h>
1480005 #include <size_t.h>
1480006 #include <stdarg.h>
1480007 #include <stdint.h>
1480008 #include <time.h>
1480009 #include <unistd.h>
1480010 #include <kernel/lib_s.h>
1480011 //----------------------------------------------------------
1480012 void k_exit (void);
1480013 unsigned int k_sleep (unsigned int seconds);
1480014 int k_usleep (useconds_t usec);
1480015 char *k_gets (char *s);
1480016 void k_perror (const char *s);
1480017 int k_printf (const char *restrict format, ...);
1480018 int k_stime (time_t * timer);
1480019 int k_vprintf (const char *restrict format, va_list arg);
1480020 int k_vsprintf (char *restrict string,
1480021 const char *restrict format, va_list arg);
1480022 //clock_t k_clock (void);
1480023 #define k_clock() (s_clock ((uid_t) 0))
1480024 #define k_time(t) (s_time ((pid_t) 0, t))
1480025 //----------------------------------------------------------
1480026 #endif
|
|
94.7.1
kernel/lib_k/k_exit.s
Si veda la sezione 93.11.
1490001 .global k_exit
1490002 #------------------------------------------------------
1490003 .text
1490004 #------------------------------------------------------
1490005 .align 4
1490006 k_exit:
1490007 halt:
1490008 hlt
1490009 jmp halt
|
|
94.7.2
kernel/lib_k/k_gets.c
Si veda la sezione 93.11.
1500001 #include <kernel/lib_k.h>
1500002 #include <kernel/driver/kbd.h>
1500003 //----------------------------------------------------------
1500004 char *
1500005 k_gets (char *s)
1500006 {
1500007 int i;
1500008 //
1500009 // Legge kbd.char.
1500010 //
1500011 for (i = 0; i < 256; i++)
1500012 {
1500013 while (kbd.key == 0)
1500014 {
1500015 //
1500016 // Attende un carattere.
1500017 //
1500018 ;
1500019 }
1500020 s[i] = kbd.key;
1500021 kbd.key = 0;
1500022 if (s[i] == '\n')
1500023 {
1500024 s[i] = 0;
1500025 break;
1500026 }
1500027 }
1500028 return s;
1500029 }
|
|
94.7.3
kernel/lib_k/k_perror.c
Si veda la sezione 93.11.
1510001 #include <kernel/lib_k.h>
1510002 #include <errno.h>
1510003 //----------------------------------------------------------
1510004 void
1510005 k_perror (const char *s)
1510006 {
1510007 //
1510008 // If errno is zero, there is nothing to show.
1510009 //
1510010 if (errno == 0)
1510011 {
1510012 return;
1510013 }
1510014 //
1510015 // Show the string if there is one.
1510016 //
1510017 if (s != NULL && strlen (s) > 0)
1510018 {
1510019 k_printf ("%s: ", s);
1510020 }
1510021 //
1510022 // Show the translated error.
1510023 //
1510024 if (errfn[0] != 0 && errln != 0)
1510025 {
1510026 k_printf ("[%s:%u:%i] %s\n",
1510027 errfn, errln, errno, strerror (errno));
1510028 }
1510029 else
1510030 {
1510031 k_printf ("[%i] %s\n", errno, strerror (errno));
1510032 }
1510033 }
|
|
94.7.4
kernel/lib_k/k_printf.c
Si veda la sezione 93.11.
1520001 #include <stdarg.h>
1520002 #include <kernel/lib_k.h>
1520003 //----------------------------------------------------------
1520004 int
1520005 k_printf (const char *restrict format, ...)
1520006 {
1520007 va_list ap;
1520008 va_start (ap, format);
1520009 return k_vprintf (format, ap);
1520010 }
|
|
94.7.5
kernel/lib_k/k_sleep.c
Si veda la sezione 93.11.
1530001 #include <kernel/lib_k.h>
1530002 #include <kernel/lib_s.h>
1530003 #include <kernel/proc.h>
1530004 #include <time.h>
1530005 //----------------------------------------------------------
1530006 unsigned int
1530007 k_sleep (unsigned int seconds)
1530008 {
1530009 clock_t time_start;
1530010 clock_t time_now;
1530011 clock_t time_elapsed;
1530012 clock_t time = seconds * CLOCKS_PER_SEC;
1530013 unsigned long long int loops;
1530014 //
1530015 // Calculate how many times the following loop
1530016 // should
1530017 // be run to get the requested time.
1530018 //
1530019 loops = proc_loops_per_clock * time;
1530020 //
1530021 // Do a wasting time loop.
1530022 //
1530023 time_elapsed = 0;
1530024 time_start = s_clock ((pid_t) 0);
1530025 //
1530026 // If the function `s_clock()' can help, it will
1530027 // exit even if the loop is become slow, but the
1530028 // time was correctly accounted and is elapsed.
1530029 //
1530030 for (; time_elapsed < time && loops > 0; loops--)
1530031 {
1530032 time_now = s_clock ((pid_t) 0);
1530033 time_elapsed = time_now - time_start;
1530034 }
1530035 //
1530036 // The sleep is always complete.
1530037 //
1530038 return (0);
1530039 }
|
|
94.7.6
kernel/lib_k/k_stime.c
Si veda la sezione 93.11.
1540001 #include <kernel/lib_k.h>
1540002 //----------------------------------------------------------
1540003 extern clock_t _clock_time; // uint64_t
1540004 //----------------------------------------------------------
1540005 int
1540006 k_stime (time_t * timer)
1540007 {
1540008 _clock_time = (*timer * CLOCKS_PER_SEC);
1540009 return (0);
1540010 }
|
|
94.7.7
kernel/lib_k/k_usleep.c
Si veda la sezione 93.11.
1550001 #include <kernel/lib_k.h>
1550002 #include <kernel/lib_s.h>
1550003 #include <kernel/proc.h>
1550004 #include <time.h>
1550005 #include <unistd.h>
1550006 //----------------------------------------------------------
1550007 int
1550008 k_usleep (useconds_t usec)
1550009 {
1550010 clock_t time_start;
1550011 clock_t time_now;
1550012 clock_t time_elapsed;
1550013 clock_t time;
1550014 unsigned long long int loops;
1550015 //
1550016 // Calculate time, in terms of internal clocks
1550017 //
1550018 if (usec < 10000000)
1550019 {
1550020 time = (usec * CLOCKS_PER_SEC) / 1000000;
1550021 }
1550022 else
1550023 {
1550024 time = (usec / 1000000) * CLOCKS_PER_SEC;
1550025 }
1550026 //
1550027 // Fix time: if it is zero, it means that it was
1550028 // requested a sleep
1550029 // shorter than the internal clock timer impulse.
1550030 // So, if it is zero,
1550031 // correct to at least a one.
1550032 //
1550033 if (time == 0 && usec != 0)
1550034 time = 1;
1550035 //
1550036 // Calculate how many times the following loop
1550037 // should
1550038 // be run to get the requested time.
1550039 //
1550040 loops = proc_loops_per_clock * time;
1550041 //
1550042 // Do a wasting time loop.
1550043 //
1550044 time_elapsed = 0;
1550045 time_start = s_clock ((pid_t) 0);
1550046 //
1550047 // If the function `s_clock()' can help, it will
1550048 // exit even if the loop is become slow, but the
1550049 // time was correctly accounted and is elapsed.
1550050 //
1550051 for (; time_elapsed < time && loops > 0; loops--)
1550052 {
1550053 time_now = s_clock ((pid_t) 0);
1550054 time_elapsed = time_now - time_start;
1550055 }
1550056 //
1550057 // The sleep is always complete.
1550058 //
1550059 return (0);
1550060 }
|
|
94.7.8
kernel/lib_k/k_vprintf.c
Si veda la sezione 93.11.
1560001 #include <kernel/lib_k.h>
1560002 #include <stdio.h>
1560003 #include <kernel/dev.h>
1560004 //----------------------------------------------------------
1560005 int
1560006 k_vprintf (const char *restrict format, va_list arg)
1560007 {
1560008 size_t size = BUFSIZ;
1560009 char string[BUFSIZ];
1560010 int status;
1560011 //
1560012 // At the moment, set `string' to be a null string.
1560013 //
1560014 string[0] = 0;
1560015 //
1560016 // Get the string, that must be limited to `size'
1560017 // bytes.
1560018 //
1560019 status = vsnprintf (string, size, format, arg);
1560020 //
1560021 //
1560022 //
1560023 if (status < 0)
1560024 {
1560025 //
1560026 // Variable `errno' is not updated.
1560027 //
1560028 return (status);
1560029 }
1560030 //
1560031 // Get size.
1560032 //
1560033 size = status;
1560034 //
1560035 // Write to the first console.
1560036 //
1560037 dev_io ((pid_t) 0, DEV_CONSOLE0, DEV_WRITE,
1560038 (off_t) 0, string, size, NULL);
1560039 //
1560040 // Return the same value obtained from `vsnprintf()'
1560041 //
1560042 return status;
1560043 }
|
|
94.7.9
kernel/lib_k/k_vsprintf.c
Si veda la sezione 93.11.
1570001 #include <stdarg.h>
1570002 #include <kernel/lib_k.h>
1570003 #include <stdio.h>
1570004 //----------------------------------------------------------
1570005 int
1570006 k_vsprintf (char *restrict string,
1570007 const char *restrict format, va_list arg)
1570008 {
1570009 int status;
1570010 status = vsnprintf (string, BUFSIZ, format, arg);
1570011 return status;
1570012 }
|
|
94.8
os32: «kernel/lib_s.h»
Si veda la sezione 93.12.
1580001 #ifndef _KERNEL_LIB_S_H
1580002 #define _KERNEL_LIB_S_H 1
1580003 //----------------------------------------------------------
1580004 #include <sys/types.h>
1580005 #include <sys/stat.h>
1580006 #include <kernel/fs.h>
1580007 #include <sys/os32.h>
1580008 #include <stddef.h>
1580009 #include <stdint.h>
1580010 #include <time.h>
1580011 #include <termios.h>
1580012 #include <setjmp.h>
1580013 //----------------------------------------------------------
1580014 void s__exit (pid_t pid, int status);
1580015 int s_brk (pid_t pid, void *address);
1580016 void *s_sbrk (pid_t pid, intptr_t increment);
1580017 pid_t s_fork (pid_t ppid);
1580018 int s_kill (pid_t pid_killer, pid_t pid_target, int sig);
1580019 void s_longjmp (pid_t pid, jmp_buf env, int val);
1580020 int s_seteuid (pid_t pid, uid_t euid);
1580021 int s_setjmp (pid_t pid, jmp_buf env);
1580022 int s_setuid (pid_t pid, uid_t uid);
1580023 int s_setegid (pid_t pid, gid_t egid);
1580024 int s_setgid (pid_t pid, gid_t gid);
1580025 pid_t s_wait (pid_t pid, int *status);
1580026 sighandler_t s_signal (pid_t pid, int sig,
1580027 sighandler_t handler,
1580028 uintptr_t wrapper);
1580029 //----------------------------------------------------------
1580030 int s_chdir (pid_t pid, const char *path);
1580031 int s_chmod (pid_t pid, const char *path, mode_t mode);
1580032 int s_chown (pid_t pid, const char *path, uid_t uid,
1580033 gid_t gid);
1580034 int s_link (pid_t pid, const char *path_old,
1580035 const char *path_new);
1580036 int s_mkdir (pid_t pid, const char *path, mode_t mode);
1580037 int s_mknod (pid_t pid, const char *path, mode_t mode,
1580038 dev_t device);
1580039 int s_open (pid_t pid, const char *path, int oflags,
1580040 mode_t mode);
1580041 int s_stat (pid_t pid, const char *path,
1580042 struct stat *buffer);
1580043 int s_unlink (pid_t pid, const char *path);
1580044 //
1580045 int s_pipe (pid_t pid, int pipefd[2]);
1580046 //
1580047 int s_close (pid_t pid, int fdn);
1580048 int s_dup (pid_t pid, int fdn_old);
1580049 int s_dup2 (pid_t pid, int fdn_old, int fdn_new);
1580050 int s_fchmod (pid_t pid, int fdn, mode_t mode);
1580051 int s_fchown (pid_t pid, int fdn, uid_t uid, gid_t gid);
1580052 int s_fcntl (pid_t pid, int fdn, int cmd, int arg);
1580053 int s_fstat (pid_t pid, int fdn, struct stat *buffer);
1580054 off_t s_lseek (pid_t pid, int fdn, off_t offset,
1580055 int whence);
1580056 ssize_t s_read (pid_t pid, int fdn, void *buffer,
1580057 size_t count);
1580058 ssize_t s_write (pid_t pid, int fdn,
1580059 const void *buffer, size_t count);
1580060 //
1580061 int s_mount (pid_t pid, const char *path_dev,
1580062 const char *path_mnt, int options);
1580063 int s_umount (pid_t pid, const char *path_mnt);
1580064 //----------------------------------------------------------
1580065 int s_accept (pid_t pid, int sfdn,
1580066 struct sockaddr *addr, socklen_t * addrlen);
1580067 int s_bind (pid_t pid, int sfdn,
1580068 const struct sockaddr *addr, socklen_t addrlen);
1580069 int s_connect (pid_t pid, int sfdn,
1580070 const struct sockaddr *addr,
1580071 socklen_t addrlen);
1580072 int s_listen (pid_t pid, int sfdn, int backlog);
1580073 int s_socket (pid_t pid, int family, int type,
1580074 int protocol);
1580075 ssize_t s_send (pid_t pid, int sfdn,
1580076 const void *buffer, size_t size, int flags);
1580077 ssize_t s_recv (pid_t pid, int sfdn, void *buffer,
1580078 size_t size, int flags);
1580079 ssize_t s_recvfrom (pid_t pid, int sfdn, void *buffer,
1580080 size_t length, int flags,
1580081 struct sockaddr *addrfrom,
1580082 socklen_t * addrlen);
1580083 //
1580084 int s_ipconfig (pid_t pid, int n, h_addr_t address, int m);
1580085 int s_routeadd (pid_t pid, h_addr_t destination, int m,
1580086 h_addr_t router, int device);
1580087 int s_routedel (pid_t pid, h_addr_t destination, int m);
1580088 //----------------------------------------------------------
1580089 int s_tcgetattr (pid_t pid, int fdn,
1580090 struct termios *termios_p);
1580091 int s_tcsetattr (pid_t pid, int fdn, int action,
1580092 struct termios *termios_p);
1580093 //----------------------------------------------------------
1580094 clock_t s_clock (pid_t pid); // [p]
1580095 time_t s_time (pid_t pid, time_t * timer); // [p]
1580096 int s_stime (pid_t pid, time_t * timer);
1580097 //
1580098 // [p] The PID information, here, is not used. The
1580099 // argument is required only for syntax coherence
1580100 // with other functions, that do
1580101 // system calls, inside the kernel.
1580102 //
1580103 //----------------------------------------------------------
1580104 #endif
|
|
94.8.1
kernel/lib_s/s__exit.c
Si veda la sezione 87.2.
1590001 #include <errno.h>
1590002 #include <kernel/proc.h>
1590003 #include <kernel/lib_k.h>
1590004 #include <kernel/lib_s.h>
1590005 //----------------------------------------------------------
1590006 void
1590007 s__exit (pid_t pid, int status)
1590008 {
1590009 pid_t child;
1590010 pid_t parent = proc_table[pid].ppid;
1590011 int proc_count;
1590012 pid_t extra;
1590013 int sigchld = 0;
1590014 int fdn;
1590015 tty_t *tty;
1590016 int closed;
1590017 fd_t *fd;
1590018 //
1590019 proc_table[pid].status = PROC_ZOMBIE;
1590020 proc_table[pid].ret = status;
1590021 proc_table[pid].sig_status = 0;
1590022 proc_table[pid].sig_ignore = 0;
1590023 //
1590024 // Close files.
1590025 //
1590026 for (fdn = 0; fdn < OPEN_MAX; fdn++)
1590027 {
1590028 closed = s_close (pid, fdn);
1590029 //
1590030 // Close might fail for work in progress.
1590031 //
1590032 if (closed < 0 && errno == EINPROGRESS)
1590033 {
1590034 //
1590035 // Should be a socket, but close badly,
1590036 // because we cannot wait.
1590037 //
1590038 fd = fd_reference (pid, &fdn);
1590039 if (fd->file->sock != NULL)
1590040 {
1590041 fd->file->sock->active = 0;
1590042 s_close (pid, fdn);
1590043 }
1590044 }
1590045 }
1590046 //
1590047 // Close current directory.
1590048 //
1590049 inode_put (proc_table[pid].inode_cwd);
1590050 //
1590051 // Close the controlling terminal, if it is a
1590052 // process leader with
1590053 // such a terminal.
1590054 //
1590055 if (proc_table[pid].pgrp == pid
1590056 && proc_table[pid].device_tty != 0)
1590057 {
1590058 tty = tty_reference (proc_table[pid].device_tty);
1590059 //
1590060 // Verify.
1590061 //
1590062 if (tty == NULL)
1590063 {
1590064 //
1590065 // Show a kernel message.
1590066 //
1590067 k_printf
1590068 ("kernel alert: cannot find the "
1590069 "terminal item "
1590070 "for device 0x%04x!\n",
1590071 (int) proc_table[pid].device_tty);
1590072 }
1590073 else if (tty->pgrp != pid)
1590074 {
1590075 //
1590076 // Show a kernel message.
1590077 //
1590078 k_printf
1590079 ("kernel alert: terminal "
1590080 "device 0x%04x should "
1590081 "be associated to the "
1590082 "process group %i, but it "
1590083 "is instead related to "
1590084 "process group %i!\n",
1590085 (int) proc_table[pid].device_tty,
1590086 (int) pid, (int) tty->pgrp);
1590087 }
1590088 else
1590089 {
1590090 tty->pgrp = 0;
1590091 }
1590092 }
1590093 //
1590094 // Data and text might share the same address space.
1590095 // If they are are on different places, then must
1590096 // verify if the text is not shared by other
1590097 // processes.
1590098 //
1590099 if (proc_table[pid].domain_data == 0)
1590100 {
1590101 //
1590102 // Text and data are together.
1590103 //
1590104 mb_free (proc_table[pid].address_text,
1590105 (proc_table[pid].domain_text
1590106 + proc_table[pid].extra_data));
1590107 }
1590108 else
1590109 {
1590110 //
1590111 // Data is separate and is to be removed alone.
1590112 //
1590113 mb_free (proc_table[pid].address_data,
1590114 (proc_table[pid].domain_data
1590115 + proc_table[pid].extra_data));
1590116 //
1590117 // Now must verify if no other process uses the
1590118 // same text
1590119 // memory.
1590120 //
1590121 for (proc_count = 0, extra = 0;
1590122 extra < PROCESS_MAX; extra++)
1590123 {
1590124 if (proc_table[extra].status == PROC_EMPTY ||
1590125 proc_table[extra].status == PROC_ZOMBIE)
1590126 {
1590127 continue;
1590128 }
1590129 if (proc_table[pid].address_text
1590130 == proc_table[extra].address_text)
1590131 {
1590132 proc_count++;
1590133 }
1590134 }
1590135 if (proc_count == 0)
1590136 {
1590137 //
1590138 // The code segment can be released, because
1590139 // no other process, except the current one
1590140 // (to be closed), is using it.
1590141 //
1590142 mb_free (proc_table[pid].address_text,
1590143 proc_table[pid].domain_text);
1590144 }
1590145 }
1590146 //
1590147 // Abandon children to `init' ((pid_t) 1).
1590148 //
1590149 for (child = 1; child < PROCESS_MAX; child++)
1590150 {
1590151 if (proc_table[child].status != PROC_EMPTY
1590152 && proc_table[child].ppid == pid)
1590153 {
1590154 proc_table[child].ppid = 1; // Son of
1590155 // `init'.
1590156 if (proc_table[child].status == PROC_ZOMBIE)
1590157 {
1590158 sigchld = 1; // Must send a SIGCHLD
1590159 // to `init'.
1590160 }
1590161 }
1590162 }
1590163 //
1590164 // SIGCHLD to `init'.
1590165 //
1590166 if (sigchld
1590167 && pid != 1
1590168 && proc_table[1].status != PROC_EMPTY
1590169 && proc_table[1].status != PROC_ZOMBIE)
1590170 {
1590171 proc_sig_on ((pid_t) 1, SIGCHLD);
1590172 }
1590173 //
1590174 // Announce to the parent the death of its child.
1590175 //
1590176 if (pid != parent
1590177 && proc_table[parent].status != PROC_EMPTY)
1590178 {
1590179 proc_sig_on (parent, SIGCHLD);
1590180 }
1590181 }
|
|
94.8.2
kernel/lib_s/s_accept.c
Si veda la sezione 87.3.
1600001 #include <kernel/proc.h>
1600002 #include <kernel/lib_s.h>
1600003 #include <kernel/lib_k.h>
1600004 #include <errno.h>
1600005 #include <fcntl.h>
1600006 #include <sys/socket.h>
1600007 #include <arpa/inet.h>
1600008 //----------------------------------------------------------
1600009 int
1600010 s_accept (pid_t pid, int sfdn, struct sockaddr *addr,
1600011 socklen_t * addrlen)
1600012 {
1600013 fd_t *sfd;
1600014 fd_t *sfd2;
1600015 int sfdn2;
1600016 struct sockaddr_in sa;
1600017 int q;
1600018 //
1600019 // Get file descriptor and verify that it is a
1600020 // socket.
1600021 //
1600022 sfd = fd_reference (pid, &sfdn);
1600023 if (sfd == NULL || sfd->file == NULL)
1600024 {
1600025 errset (EBADF); // Bad file descriptor.
1600026 return (-1);
1600027 }
1600028 if (sfd->file->sock == NULL)
1600029 {
1600030 errset (ENOTSOCK); // Not a socket.
1600031 return (-1);
1600032 }
1600033 //
1600034 // The socket must be a stream.
1600035 //
1600036 if (sfd->file->sock->type != SOCK_STREAM)
1600037 {
1600038 errset (EOPNOTSUPP);
1600039 return (-1);
1600040 }
1600041 //
1600042 // The socket must be a TCP stream: no other stream
1600043 // types are
1600044 // available.
1600045 //
1600046 if (sfd->file->sock->protocol != IPPROTO_TCP)
1600047 {
1600048 errset (EOPNOTSUPP);
1600049 return (-1);
1600050 }
1600051 //
1600052 // The socket itself must be listening.
1600053 //
1600054 if (sfd->file->sock->tcp.conn != TCP_LISTEN)
1600055 {
1600056 errset (EINVAL);
1600057 return (-1);
1600058 }
1600059 //
1600060 // The connections must be related to the same PID.
1600061 //
1600062 if (sfd->file->sock->tcp.listen_pid != pid)
1600063 {
1600064 k_printf
1600065 ("[%s] the connection pid %i is not the same "
1600066 "as the current pid %i!\n", __func__,
1600067 sfd->file->sock->tcp.listen_pid, pid);
1600068 errset (EUNKNOWN);
1600069 return (-1);
1600070 }
1600071 //
1600072 // Ok: find a connected socket from the queue.
1600073 //
1600074 for (q = 0; q < sfd->file->sock->tcp.listen_max; q++)
1600075 {
1600076 if (sfd->file->sock->tcp.listen_queue[q] != -1)
1600077 {
1600078 //
1600079 // Found.
1600080 //
1600081 break;
1600082 }
1600083 }
1600084 if (q >= sfd->file->sock->tcp.listen_max)
1600085 {
1600086 //
1600087 // At the moment, there is no new connection.
1600088 //
1600089 errset (EAGAIN); // Try again.
1600090 return (-1);
1600091 }
1600092 //
1600093 // Descriptor found: check it.
1600094 //
1600095 sfdn2 = sfd->file->sock->tcp.listen_queue[q];
1600096 sfd2 = fd_reference (pid, &sfdn2);
1600097 if (sfd2 == NULL || sfd->file == NULL)
1600098 {
1600099 k_printf
1600100 ("[%s] the connected file descriptor %i "
1600101 "for process %i is not a file descriptor!",
1600102 __func__, sfdn2, pid);
1600103 errset (EBADF); // Bad file descriptor.
1600104 return (-1);
1600105 }
1600106 if (sfd2->file->sock == NULL)
1600107 {
1600108 k_printf
1600109 ("[%s] the connected file descriptor %i "
1600110 "for process %i is not a socket!", __func__,
1600111 sfdn2, pid);
1600112 errset (ENOTSOCK); // Not a socket.
1600113 return (-1);
1600114 }
1600115 //
1600116 // Ok.
1600117 //
1600118 if (addrlen != NULL && addr != NULL && *addrlen > 0)
1600119 {
1600120 sa.sin_family = AF_INET;
1600121 sa.sin_port = htons (sfd2->file->sock->rport);
1600122 sa.sin_addr.s_addr = htonl (sfd2->file->sock->raddr);
1600123 //
1600124 memcpy (addr, &sa,
1600125 min (sizeof (sa), (size_t) * addrlen));
1600126 *addrlen = sizeof (sa);
1600127 }
1600128 //
1600129 // Reset the queue element and return.
1600130 //
1600131 sfd->file->sock->tcp.listen_queue[q] = -1;
1600132 return (sfdn2);
1600133 }
|
|
94.8.3
kernel/lib_s/s_bind.c
Si veda la sezione 87.4.
1610001 #include <kernel/proc.h>
1610002 #include <kernel/lib_s.h>
1610003 #include <kernel/lib_k.h>
1610004 #include <errno.h>
1610005 #include <fcntl.h>
1610006 #include <sys/socket.h>
1610007 #include <arpa/inet.h>
1610008 //----------------------------------------------------------
1610009 int
1610010 s_bind (pid_t pid, int sfdn,
1610011 const struct sockaddr *addr, socklen_t addrlen)
1610012 {
1610013 fd_t *sfd;
1610014 struct sockaddr_in *sin;
1610015 proc_t *ps = proc_reference (pid);
1610016 int i;
1610017 clock_t clock_time;
1610018 //
1610019 // Get file descriptor and verify that it is a
1610020 // socket.
1610021 //
1610022 sfd = fd_reference (pid, &sfdn);
1610023 if (sfd == NULL || sfd->file == NULL)
1610024 {
1610025 errset (EBADF); // Bad file descriptor.
1610026 return (-1);
1610027 }
1610028 if (sfd->file->sock == NULL)
1610029 {
1610030 errset (ENOTSOCK); // Not a socket.
1610031 return (-1);
1610032 }
1610033 //
1610034 // Verify to have a valid address pointer.
1610035 //
1610036 if (addr == NULL)
1610037 {
1610038 errset (EINVAL);
1610039 return (-1);
1610040 }
1610041 //
1610042 // Check minimal address size.
1610043 //
1610044 if (addrlen < sizeof (struct sockaddr))
1610045 {
1610046 errset (EINVAL);
1610047 return (-1);
1610048 }
1610049 //
1610050 //
1610051 //
1610052 if (addr->sa_family == AF_INET)
1610053 {
1610054 sin = (struct sockaddr_in *) addr;
1610055 //
1610056 // The source address might be zero, to tell
1610057 // that any local
1610058 // address is valid.
1610059 //
1610060 // If it is a TCP/UDP protocol, must have valid
1610061 // ports.
1610062 //
1610063 if (sfd->file->sock->protocol == IPPROTO_TCP
1610064 || sfd->file->sock->protocol == IPPROTO_UDP)
1610065 {
1610066 //
1610067 // Local port.
1610068 //
1610069 if (ntohs (sin->sin_port) == 0)
1610070 {
1610071 //
1610072 // Missing the local port.
1610073 //
1610074 errset (EADDRNOTAVAIL);
1610075 return (-1);
1610076 }
1610077 //
1610078 // If the local port is privileged, must
1610079 // have EUID == 0.
1610080 //
1610081 if (ntohs (sin->sin_port) < 1024)
1610082 {
1610083 if (ps->euid != 0)
1610084 {
1610085 //
1610086 // Missing privileges.
1610087 //
1610088 errset (EACCES);
1610089 return (-1);
1610090 }
1610091 }
1610092 //
1610093 // If the local port is not given, a default
1610094 // one is assigned.
1610095 //
1610096 if (sfd->file->sock->lport == 0)
1610097 {
1610098 //
1610099 // Must find a free one.
1610100 //
1610101 sfd->file->sock->lport = sock_free_port ();
1610102 if (sfd->file->sock->lport == 0)
1610103 {
1610104 //
1610105 // No port is available.
1610106 //
1610107 errset (EAGAIN);
1610108 return (-1);
1610109 }
1610110 }
1610111 }
1610112 else
1610113 {
1610114 //
1610115 // Not supported.
1610116 //
1610117 errset (EOPNOTSUPP);
1610118 return (-1);
1610119 }
1610120 //
1610121 // Update the socket.
1610122 //
1610123 sfd->file->sock->family = sin->sin_family;
1610124 sfd->file->sock->laddr = ntohl (sin->sin_addr.s_addr);
1610125 sfd->file->sock->lport = ntohs (sin->sin_port);
1610126 // sfd->file->sock->bind = 1;
1610127 //
1610128 // Reset read packets clock time.
1610129 //
1610130 clock_time = s_clock (pid);
1610131 for (i = 0; i < IP_MAX_PACKETS; i++)
1610132 {
1610133 sfd->file->sock->read.clock[i] = clock_time;
1610134 }
1610135 }
1610136 else
1610137 {
1610138 //
1610139 // Unsupported family.
1610140 //
1610141 errset (EAFNOSUPPORT);
1610142 return (-1);
1610143 }
1610144 //
1610145 // Ok.
1610146 //
1610147 return (0);
1610148 }
|
|
94.8.4
kernel/lib_s/s_brk.c
Si veda la sezione 87.5.
1620001 #include <errno.h>
1620002 #include <kernel/proc.h>
1620003 #include <kernel/memory.h>
1620004 #include <kernel/lib_k.h>
1620005 #include <kernel/lib_s.h>
1620006 //----------------------------------------------------------
1620007 #define DEBUG 0
1620008 //----------------------------------------------------------
1620009 int
1620010 s_brk (pid_t pid, void *address)
1620011 {
1620012 size_t requested_size;
1620013 size_t requested_extra;
1620014 addr_t previous_address_text;
1620015 size_t previous_domain_text;
1620016 addr_t previous_address_data;
1620017 size_t previous_domain_data;
1620018 size_t previous_extra;
1620019 addr_t allocated_text;
1620020 addr_t allocated_data;
1620021 int status;
1620022 //
1620023 // All segments start form ((void *) 0), so the new
1620024 // address requested is equivalent to the new size
1620025 // for the data segment.
1620026 //
1620027 requested_size = (size_t) address;
1620028 //
1620029 // Check if it is possible to get the new size:
1620030 // cannot be less
1620031 // then the original segment size.
1620032 //
1620033 if (proc_table[pid].domain_data == 0)
1620034 {
1620035 if (proc_table[pid].domain_text > requested_size)
1620036 {
1620037 requested_extra = 0;
1620038 }
1620039 else
1620040 {
1620041 requested_extra = requested_size
1620042 - proc_table[pid].domain_text;
1620043 }
1620044 }
1620045 else
1620046 {
1620047 if (proc_table[pid].domain_data > requested_size)
1620048 {
1620049 requested_extra = 0;
1620050 }
1620051 else
1620052 {
1620053 requested_extra = requested_size
1620054 - proc_table[pid].domain_data;
1620055 }
1620056 }
1620057 //
1620058 // Now make shure that the new value is a multiple
1620059 // of
1620060 // MEM_BLOCK_SIZE!
1620061 //
1620062 if (requested_extra % MEM_BLOCK_SIZE)
1620063 {
1620064 requested_extra =
1620065 (((requested_extra / MEM_BLOCK_SIZE) +
1620066 1) * MEM_BLOCK_SIZE);
1620067 }
1620068 //
1620069 // Now resize the process.
1620070 //
1620071 if (requested_extra == proc_table[pid].extra_data)
1620072 {
1620073 //
1620074 // Nothing have to change.
1620075 //
1620076 return (0);
1620077 }
1620078 else if (requested_extra < proc_table[pid].extra_data)
1620079 {
1620080 //
1620081 // Just reduce.
1620082 //
1620083 previous_extra = proc_table[pid].extra_data;
1620084 proc_table[pid].extra_data = requested_extra;
1620085 //
1620086 // Update process DATA segment inside the GDT
1620087 // table.
1620088 //
1620089 if (proc_table[pid].domain_data > 0)
1620090 {
1620091 gdt_segment (gdt_pid_to_segment_data (pid),
1620092 (uint32_t)
1620093 proc_table[pid].address_data,
1620094 (uint32_t) ((proc_table
1620095 [pid].domain_data +
1620096 proc_table
1620097 [pid].extra_data) /
1620098 MEM_BLOCK_SIZE), 1, 0,
1620099 0);
1620100 }
1620101 else
1620102 {
1620103 gdt_segment (gdt_pid_to_segment_data (pid),
1620104 (uint32_t)
1620105 proc_table[pid].address_text,
1620106 (uint32_t) ((proc_table
1620107 [pid].domain_text +
1620108 proc_table
1620109 [pid].extra_data) /
1620110 MEM_BLOCK_SIZE), 1, 0,
1620111 0);
1620112 }
1620113 //
1620114 // Release memory.
1620115 //
1620116 if (proc_table[pid].domain_data > 0)
1620117 {
1620118 status =
1620119 mb_reduce ((proc_table[pid].address_data +
1620120 proc_table[pid].domain_data),
1620121 proc_table[pid].extra_data,
1620122 previous_extra);
1620123 }
1620124 else
1620125 {
1620126 status =
1620127 mb_reduce ((proc_table[pid].address_text +
1620128 proc_table[pid].domain_text),
1620129 proc_table[pid].extra_data,
1620130 previous_extra);
1620131 }
1620132 //
1620133 if (status < 0)
1620134 {
1620135 //
1620136 // What happened?
1620137 //
1620138 k_perror (NULL);
1620139 }
1620140 }
1620141 else
1620142 {
1620143 //
1620144 // A bigger size was requested. Save previous
1620145 // information.
1620146 //
1620147 previous_address_text = proc_table[pid].address_text;
1620148 previous_domain_text = proc_table[pid].domain_text;
1620149 previous_address_data = proc_table[pid].address_data;
1620150 previous_domain_data = proc_table[pid].domain_data;
1620151 previous_extra = proc_table[pid].extra_data;
1620152 //
1620153 // Allocate memory for text,
1620154 // if text and data are inside the same address
1620155 // space;
1620156 // otherwise only the data segment is involved.
1620157 //
1620158 if (proc_table[pid].domain_data == 0)
1620159 {
1620160 allocated_text =
1620161 mb_alloc_size (proc_table[pid].domain_text +
1620162 requested_extra);
1620163 //
1620164 if (allocated_text == 0)
1620165 {
1620166 errset (ENOMEM); // Not enough space.
1620167 return (-1);
1620168 }
1620169 //
1620170 if (DEBUG)
1620171 {
1620172 k_printf ("%s:%i:mb_alloc_size(%zi)",
1620173 __FILE__, __LINE__,
1620174 (proc_table[pid].domain_text
1620175 + requested_extra));
1620176 }
1620177 }
1620178 //
1620179 // Allocate memory for data, if necessary.
1620180 //
1620181 if (proc_table[pid].domain_data > 0)
1620182 {
1620183 allocated_data =
1620184 mb_alloc_size (proc_table[pid].domain_data +
1620185 requested_extra);
1620186 //
1620187 if (allocated_data == 0)
1620188 {
1620189 //
1620190 // Please note that, if we are here, no
1620191 // memory
1620192 // for the text was allocated!
1620193 //
1620194 errset (ENOMEM); // Not enough space.
1620195 return (-1);
1620196 }
1620197 //
1620198 if (DEBUG)
1620199 {
1620200 k_printf ("%s:%i:mb_alloc_size(%zi)",
1620201 __FILE__, __LINE__,
1620202 (proc_table[pid].domain_data
1620203 + requested_extra));
1620204 }
1620205 }
1620206 //
1620207 // Copy the process text and, data in memory: if
1620208 // size is zero, no copy is made. But the text
1620209 // is
1620210 // copied only if text and data live together.
1620211 //
1620212 if (proc_table[pid].domain_data == 0)
1620213 {
1620214 memcpy ((void *) allocated_text,
1620215 (void *) proc_table[pid].address_text,
1620216 (size_t) (proc_table[pid].domain_text +
1620217 proc_table[pid].extra_data));
1620218 }
1620219 else
1620220 {
1620221 memcpy ((void *) allocated_data,
1620222 (void *) proc_table[pid].address_data,
1620223 (size_t) (proc_table[pid].domain_data +
1620224 proc_table[pid].extra_data));
1620225 }
1620226 //
1620227 // Update process information.
1620228 //
1620229 if (proc_table[pid].domain_data == 0)
1620230 {
1620231 proc_table[pid].address_text = allocated_text;
1620232 }
1620233 else
1620234 {
1620235 proc_table[pid].address_data = allocated_data;
1620236 }
1620237 proc_table[pid].extra_data = requested_extra;
1620238 //
1620239 // Update process TEXT segment inside the GDT
1620240 // table.
1620241 //
1620242 gdt_segment (gdt_pid_to_segment_text (pid),
1620243 (uint32_t) proc_table[pid].address_text,
1620244 (uint32_t) (proc_table[pid].domain_text /
1620245 MEM_BLOCK_SIZE), 1, 1, 0);
1620246 //
1620247 // Update process DATA segment inside the GDT
1620248 // table.
1620249 //
1620250 if (proc_table[pid].domain_data > 0)
1620251 {
1620252 gdt_segment (gdt_pid_to_segment_data (pid),
1620253 (uint32_t)
1620254 proc_table[pid].address_data,
1620255 (uint32_t) ((proc_table
1620256 [pid].domain_data +
1620257 proc_table
1620258 [pid].extra_data) /
1620259 MEM_BLOCK_SIZE), 1, 0,
1620260 0);
1620261 }
1620262 else
1620263 {
1620264 gdt_segment (gdt_pid_to_segment_data (pid),
1620265 (uint32_t)
1620266 proc_table[pid].address_text,
1620267 (uint32_t) ((proc_table
1620268 [pid].domain_text +
1620269 proc_table
1620270 [pid].extra_data) /
1620271 MEM_BLOCK_SIZE), 1, 0,
1620272 0);
1620273 }
1620274 //
1620275 // Now release the old memory!
1620276 //
1620277 if (proc_table[pid].domain_data == 0)
1620278 {
1620279 mb_free (previous_address_text,
1620280 previous_domain_text + previous_extra);
1620281 }
1620282 else
1620283 {
1620284 mb_free (previous_address_data,
1620285 previous_domain_data + previous_extra);
1620286 }
1620287 }
1620288 //
1620289 // Ok.
1620290 //
1620291 return (0);
1620292 }
|
|
94.8.5
kernel/lib_s/s_chdir.c
Si veda la sezione 87.6.
1630001 #include <kernel/fs.h>
1630002 #include <errno.h>
1630003 #include <kernel/proc.h>
1630004 #include <kernel/lib_s.h>
1630005 //----------------------------------------------------------
1630006 int
1630007 s_chdir (pid_t pid, const char *path)
1630008 {
1630009 proc_t *ps;
1630010 inode_t *inode_directory;
1630011 int status;
1630012 char path_directory[PATH_MAX];
1630013 //
1630014 // Get process.
1630015 //
1630016 ps = proc_reference (pid);
1630017 //
1630018 // The full directory path is needed.
1630019 //
1630020 status = path_full (path, ps->path_cwd, path_directory);
1630021 if (status < 0)
1630022 {
1630023 return (-1);
1630024 }
1630025 //
1630026 // Try to load the new directory inode.
1630027 //
1630028 inode_directory = path_inode (pid, path_directory);
1630029 if (inode_directory == NULL)
1630030 {
1630031 //
1630032 // Cannot access the directory: it does not
1630033 // exists or
1630034 // permissions are not sufficient. Variable
1630035 // `errno' is set by
1630036 // function `inode_directory()'.
1630037 //
1630038 errset (errno);
1630039 return (-1);
1630040 }
1630041 //
1630042 // Inode loaded: release the old directory and set
1630043 // the new one.
1630044 //
1630045 inode_put (ps->inode_cwd);
1630046 //
1630047 ps->inode_cwd = inode_directory;
1630048 strncpy (ps->path_cwd, path_directory, PATH_MAX);
1630049 //
1630050 // Return.
1630051 //
1630052 return (0);
1630053 }
|
|
94.8.6
kernel/lib_s/s_chmod.c
Si veda la sezione 87.7.
1640001 #include <kernel/fs.h>
1640002 #include <errno.h>
1640003 #include <kernel/proc.h>
1640004 #include <kernel/lib_s.h>
1640005 //----------------------------------------------------------
1640006 int
1640007 s_chmod (pid_t pid, const char *path, mode_t mode)
1640008 {
1640009 proc_t *ps;
1640010 inode_t *inode;
1640011 //
1640012 // Get process.
1640013 //
1640014 ps = proc_reference (pid);
1640015 //
1640016 // Try to load the file inode.
1640017 //
1640018 inode = path_inode (pid, path);
1640019 if (inode == NULL)
1640020 {
1640021 //
1640022 // Cannot access the file: it does not exists or
1640023 // permissions are
1640024 // not sufficient. Variable `errno' is set by
1640025 // function
1640026 // `inode_directory()'.
1640027 //
1640028 return (-1);
1640029 }
1640030 //
1640031 // Verify to be root or to be the owner.
1640032 //
1640033 if (ps->euid != 0 && ps->euid != inode->uid)
1640034 {
1640035 errset (EACCES); // Permission denied.
1640036 return (-1);
1640037 }
1640038 //
1640039 // Update the mode: the file type is kept and the
1640040 // rest is taken form the parameter `mode'.
1640041 //
1640042 inode->mode = (S_IFMT & inode->mode) | (~S_IFMT & mode);
1640043 //
1640044 // Save and release the inode.
1640045 //
1640046 inode->changed = 1;
1640047 inode_save (inode);
1640048 inode_put (inode);
1640049 //
1640050 // Return.
1640051 //
1640052 return (0);
1640053 }
|
|
94.8.7
kernel/lib_s/s_chown.c
Si veda la sezione 87.8.
1650001 #include <kernel/fs.h>
1650002 #include <errno.h>
1650003 #include <kernel/proc.h>
1650004 #include <kernel/lib_s.h>
1650005 //----------------------------------------------------------
1650006 int
1650007 s_chown (pid_t pid, const char *path, uid_t uid, gid_t gid)
1650008 {
1650009 proc_t *ps;
1650010 inode_t *inode;
1650011 //
1650012 // Get process.
1650013 //
1650014 ps = proc_reference (pid);
1650015 //
1650016 // Must be root, as the ability to change group is
1650017 // not considered.
1650018 //
1650019 if (ps->euid != 0)
1650020 {
1650021 errset (EPERM); // Operation not permitted.
1650022 return (-1);
1650023 }
1650024 //
1650025 // Try to load the file inode.
1650026 //
1650027 inode = path_inode (pid, path);
1650028 if (inode == NULL)
1650029 {
1650030 //
1650031 // Cannot access the file: it does not exists or
1650032 // permissions are
1650033 // not sufficient. Variable `errno' is set by
1650034 // function
1650035 // `inode_directory()'.
1650036 //
1650037 return (-1);
1650038 }
1650039 //
1650040 // Update the owner and group.
1650041 //
1650042 if (uid != -1)
1650043 {
1650044 inode->uid = uid;
1650045 inode->changed = 1;
1650046 }
1650047 if (gid != -1)
1650048 {
1650049 inode->gid = gid;
1650050 inode->changed = 1;
1650051 }
1650052 //
1650053 // Save and release the inode.
1650054 //
1650055 inode_save (inode);
1650056 inode_put (inode);
1650057 //
1650058 // Return.
1650059 //
1650060 return (0);
1650061 }
|
|
94.8.8
kernel/lib_s/s_clock.c
Si veda la sezione 87.9.
1660001 #include <kernel/lib_s.h>
1660002 //----------------------------------------------------------
1660003 extern clock_t _clock_kernel; // uint64_t
1660004 //----------------------------------------------------------
1660005 clock_t
1660006 s_clock (pid_t pid)
1660007 {
1660008 return (_clock_kernel);
1660009 }
|
|
94.8.9
kernel/lib_s/s_close.c
Si veda la sezione 87.10.
1670001 #include <kernel/proc.h>
1670002 #include <fcntl.h>
1670003 #include <errno.h>
1670004 //----------------------------------------------------------
1670005 int
1670006 s_close (pid_t pid, int fdn)
1670007 {
1670008 fd_t *fd;
1670009 int status;
1670010 //
1670011 // Get file descriptor.
1670012 //
1670013 fd = fd_reference (pid, &fdn);
1670014 if (fd == NULL || fd->file == NULL
1670015 || (fd->file->inode == NULL
1670016 && fd->file->sock == NULL))
1670017 {
1670018 errset (EBADF); // Bad file descriptor.
1670019 return (-1);
1670020 }
1670021 //
1670022 //
1670023 //
1670024 if (fd->file->inode != NULL) // Inode
1670025 {
1670026 //
1670027 // File descriptor with inode.
1670028 //
1670029 // If it is a pipe, some special things must be
1670030 // done.
1670031 //
1670032 if (S_ISFIFO (fd->file->inode->mode))
1670033 {
1670034 if (fd->fl_flags & O_RDONLY)
1670035 {
1670036 fd->file->inode->pipe_ref_read--;
1670037 if (fd->file->inode->pipe_ref_read == 0)
1670038 {
1670039 proc_wakeup_pipe_write (fd->file->inode);
1670040 }
1670041 }
1670042 //
1670043 if (fd->fl_flags & O_WRONLY)
1670044 {
1670045 fd->file->inode->pipe_ref_write--;
1670046 if (fd->file->inode->pipe_ref_write == 0)
1670047 {
1670048 proc_wakeup_pipe_read (fd->file->inode);
1670049 }
1670050 }
1670051 }
1670052 }
1670053 else // Socket
1670054 {
1670055 //
1670056 // File descriptor with socket.
1670057 //
1670058 status = tcp_close (fd->file->sock);
1670059 if (status < 0
1670060 && (errno == EINPROGRESS || errno == EALREADY))
1670061 {
1670062 errset (errno);
1670063 return (status);
1670064 }
1670065 //
1670066 // Otherwise, the socket is closed and can
1670067 // continue
1670068 // with the other references.
1670069 //
1670070 }
1670071 //
1670072 // Reduce references inside the file table item
1670073 // and remove item if it reaches zero.
1670074 //
1670075 fd->file->references--;
1670076 if (fd->file->references == 0)
1670077 {
1670078 fd->file->oflags = 0;
1670079 fd->file->inode = NULL;
1670080 //
1670081 // Put inode, or release the socket, because
1670082 // there are no more
1670083 // file references.
1670084 //
1670085 if (fd->file->inode != NULL)
1670086 {
1670087 inode_put (fd->file->inode);
1670088 }
1670089 if (fd->file->sock != NULL)
1670090 {
1670091 sock_put (fd->file->sock);
1670092 }
1670093 }
1670094 //
1670095 // Remove file descriptor.
1670096 //
1670097 fd->fl_flags = 0;
1670098 fd->fd_flags = 0;
1670099 fd->file = NULL;
1670100 //
1670101 //
1670102 //
1670103 return (0);
1670104 }
|
|
94.8.10
kernel/lib_s/s_connect.c
Si veda la sezione 87.11.
1680001 #include <kernel/proc.h>
1680002 #include <kernel/lib_s.h>
1680003 #include <kernel/lib_k.h>
1680004 #include <kernel/net/route.h>
1680005 #include <errno.h>
1680006 #include <fcntl.h>
1680007 #include <sys/socket.h>
1680008 #include <arpa/inet.h>
1680009 //----------------------------------------------------------
1680010 int
1680011 s_connect (pid_t pid, int sfdn,
1680012 const struct sockaddr *addr, socklen_t addrlen)
1680013 {
1680014 fd_t *sfd;
1680015 struct sockaddr_in *sin;
1680016 clock_t clock_time;
1680017 int i;
1680018 int status;
1680019 //
1680020 // Get file descriptor and verify that it is a
1680021 // socket.
1680022 //
1680023 sfd = fd_reference (pid, &sfdn);
1680024 if (sfd == NULL || sfd->file == NULL)
1680025 {
1680026 errset (EBADF); // Bad file descriptor.
1680027 return (-1);
1680028 }
1680029 if (sfd->file->sock == NULL)
1680030 {
1680031 errset (ENOTSOCK); // Not a socket.
1680032 return (-1);
1680033 }
1680034 //
1680035 // Verify to have a valid address pointer.
1680036 //
1680037 if (addr == NULL)
1680038 {
1680039 errset (EINVAL);
1680040 return (-1);
1680041 }
1680042 //
1680043 // Check minimal address size.
1680044 //
1680045 if (addrlen < sizeof (struct sockaddr))
1680046 {
1680047 errset (EINVAL);
1680048 return (-1);
1680049 }
1680050 //
1680051 //
1680052 //
1680053 if (addr->sa_family == AF_INET)
1680054 {
1680055 sin = (struct sockaddr_in *) addr;
1680056 //
1680057 // Check to have the destination IP address.
1680058 //
1680059 if (sin->sin_addr.s_addr == 0)
1680060 {
1680061 //
1680062 // This is not valid.
1680063 //
1680064 errset (EADDRNOTAVAIL);
1680065 return (-1);
1680066 }
1680067 //
1680068 // If it is a TCP/UDP protocol, must have valid
1680069 // ports.
1680070 //
1680071 if (sfd->file->sock->protocol == IPPROTO_TCP
1680072 || sfd->file->sock->protocol == IPPROTO_UDP)
1680073 {
1680074 //
1680075 // Remote port.
1680076 //
1680077 if (sin->sin_port == 0)
1680078 {
1680079 //
1680080 // Missing the remote port.
1680081 //
1680082 errset (EADDRNOTAVAIL);
1680083 return (-1);
1680084 }
1680085 //
1680086 // Local port.
1680087 //
1680088 if (sfd->file->sock->lport == 0)
1680089 {
1680090 //
1680091 // Must find a free one.
1680092 //
1680093 sfd->file->sock->lport = sock_free_port ();
1680094 if (sfd->file->sock->lport == 0)
1680095 {
1680096 //
1680097 // No port is available.
1680098 //
1680099 errset (EAGAIN);
1680100 return (-1);
1680101 }
1680102 }
1680103 }
1680104 //
1680105 // Update the socket, but not a TCP connection
1680106 // already
1680107 // working (TCP not connected has a zeroed
1680108 // `tcp.conn' filled).
1680109 //
1680110 if (sfd->file->sock->tcp.conn == 0
1680111 || sfd->file->sock->tcp.conn == TCP_CLOSE)
1680112 {
1680113 //
1680114 // Update the socket.
1680115 //
1680116 sfd->file->sock->family = sin->sin_family;
1680117 sfd->file->sock->raddr =
1680118 ntohl (sin->sin_addr.s_addr);
1680119 sfd->file->sock->rport = ntohs (sin->sin_port);
1680120 //
1680121 // Reset read packets clock time.
1680122 //
1680123 clock_time = s_clock (pid);
1680124 for (i = 0; i < IP_MAX_PACKETS; i++)
1680125 {
1680126 sfd->file->sock->read.clock[i] = clock_time;
1680127 }
1680128 }
1680129 else
1680130 {
1680131 //
1680132 // It *is* a TCP connection already working:
1680133 // verify that
1680134 // the socket is set as expected
1680135 //
1680136 if (sfd->file->sock->family !=
1680137 sin->sin_family
1680138 || sfd->file->sock->raddr !=
1680139 ntohl (sin->sin_addr.s_addr)
1680140 || sfd->file->sock->rport !=
1680141 ntohs (sin->sin_port))
1680142 {
1680143 //
1680144 // The socket address is changed!
1680145 //
1680146 errset (EISCONN);
1680147 return (-1);
1680148 }
1680149 }
1680150 //
1680151 // If it is a TCP, not already working, should
1680152 // connect.
1680153 // The function `tcp_connect()' will verify the
1680154 // connection
1680155 // status.
1680156 //
1680157 if (sfd->file->sock->protocol == IPPROTO_TCP)
1680158 {
1680159 //
1680160 // Be shure to have a source address.
1680161 //
1680162 if (sfd->file->sock->laddr == 0)
1680163 {
1680164 //
1680165 // Default source address: get the
1680166 // source address from the
1680167 // routing table, based on the
1680168 // destination.
1680169 //
1680170 sfd->file->sock->laddr
1680171 =
1680172 route_remote_to_local (sfd->file->
1680173 sock->raddr);
1680174 if (sfd->file->sock->laddr ==
1680175 ((h_addr_t) - 1))
1680176 {
1680177 errset (errno);
1680178 return (-1);
1680179 }
1680180 }
1680181 //
1680182 // Call tcp_connect ().
1680183 //
1680184 status = tcp_connect (sfd->file->sock);
1680185 if (status)
1680186 {
1680187 errset (errno);
1680188 }
1680189 return (status);
1680190 }
1680191 }
1680192 else
1680193 {
1680194 //
1680195 // It is not AF_INET: unsupported address
1680196 // family.
1680197 //
1680198 errset (EAFNOSUPPORT);
1680199 return (-1);
1680200 }
1680201 //
1680202 // Ok.
1680203 //
1680204 return (0);
1680205 }
|
|
94.8.11
kernel/lib_s/s_dup.c
Si veda la sezione 87.12.
1690001 #include <kernel/lib_s.h>
1690002 #include <kernel/fs.h>
1690003 //----------------------------------------------------------
1690004 int
1690005 s_dup (pid_t pid, int fdn_old)
1690006 {
1690007 return (fd_dup (pid, fdn_old, 0));
1690008 }
|
|
94.8.12
kernel/lib_s/s_dup2.c
Si veda la sezione 87.12.
1700001 #include <kernel/proc.h>
1700002 #include <kernel/lib_s.h>
1700003 #include <errno.h>
1700004 #include <fcntl.h>
1700005 //----------------------------------------------------------
1700006 int
1700007 s_dup2 (pid_t pid, int fdn_old, int fdn_new)
1700008 {
1700009 proc_t *ps;
1700010 int status;
1700011 //
1700012 // Get process.
1700013 //
1700014 ps = proc_reference (pid);
1700015 //
1700016 // Verify if `fdn_old' is a valid value.
1700017 //
1700018 if (fdn_old < 0 ||
1700019 fdn_old >= OPEN_MAX || ps->fd[fdn_old].file == NULL)
1700020 {
1700021 errset (EBADF); // Bad file descriptor.
1700022 return (-1);
1700023 }
1700024 //
1700025 // Check if `fd_old' and `fd_new' are the same.
1700026 //
1700027 if (fdn_old == fdn_new)
1700028 {
1700029 return (fdn_new);
1700030 }
1700031 //
1700032 // Close `fdn_new' if it is open and copy `fdn_old'
1700033 // into it.
1700034 //
1700035 if (ps->fd[fdn_new].file != NULL)
1700036 {
1700037 status = s_close (pid, fdn_new);
1700038 if (status != 0)
1700039 {
1700040 return (-1);
1700041 }
1700042 }
1700043 ps->fd[fdn_new].fl_flags = ps->fd[fdn_old].fl_flags;
1700044 ps->fd[fdn_new].fd_flags =
1700045 ps->fd[fdn_old].fd_flags & ~FD_CLOEXEC;
1700046 ps->fd[fdn_new].file = ps->fd[fdn_old].file;
1700047 ps->fd[fdn_new].file->references++;
1700048 return (fdn_new);
1700049 }
|
|
94.8.13
kernel/lib_s/s_fchmod.c
Si veda la sezione 87.7.
1710001 #include <kernel/proc.h>
1710002 #include <kernel/lib_s.h>
1710003 #include <sys/stat.h>
1710004 #include <errno.h>
1710005 //----------------------------------------------------------
1710006 int
1710007 s_fchmod (pid_t pid, int fdn, mode_t mode)
1710008 {
1710009 proc_t *ps;
1710010 inode_t *inode;
1710011 //
1710012 // Get process.
1710013 //
1710014 ps = proc_reference (pid);
1710015 //
1710016 // Verify if the file descriptor is valid.
1710017 //
1710018 if (ps->fd[fdn].file == NULL)
1710019 {
1710020 errset (EBADF); // Bad file descriptor.
1710021 return (-1);
1710022 }
1710023 //
1710024 // Reach the inode.
1710025 //
1710026 inode = ps->fd[fdn].file->inode;
1710027 //
1710028 // If the Inode does not exist, exit with error.
1710029 //
1710030 if (inode == NULL)
1710031 {
1710032 errset (ENOENT);
1710033 return (-1);
1710034 }
1710035 //
1710036 // Verify to be the owner, or at least to be UID ==
1710037 // 0.
1710038 //
1710039 if (ps->euid != inode->uid && ps->euid != 0)
1710040 {
1710041 errset (EACCES); // Permission denied.
1710042 return (-1);
1710043 }
1710044 //
1710045 // Update the mode: the file type is kept and the
1710046 // rest is taken form the parameter `mode'.
1710047 //
1710048 inode->mode = (S_IFMT & inode->mode) | (~S_IFMT & mode);
1710049 //
1710050 // Save the inode.
1710051 //
1710052 inode->changed = 1;
1710053 inode_save (inode);
1710054 //
1710055 // Return.
1710056 //
1710057 return (0);
1710058 }
|
|
94.8.14
kernel/lib_s/s_fchown.c
Si veda la sezione 87.8.
1720001 #include <kernel/proc.h>
1720002 #include <kernel/lib_s.h>
1720003 #include <errno.h>
1720004 //----------------------------------------------------------
1720005 int
1720006 s_fchown (pid_t pid, int fdn, uid_t uid, gid_t gid)
1720007 {
1720008 proc_t *ps;
1720009 inode_t *inode;
1720010 //
1720011 // Get process.
1720012 //
1720013 ps = proc_reference (pid);
1720014 //
1720015 // Verify if the file descriptor is valid.
1720016 //
1720017 if (ps->fd[fdn].file == NULL)
1720018 {
1720019 errset (EBADF); // Bad file descriptor.
1720020 return (-1);
1720021 }
1720022 //
1720023 // Reach the inode.
1720024 //
1720025 inode = ps->fd[fdn].file->inode;
1720026 //
1720027 // If the Inode does not exist, exit with error.
1720028 //
1720029 if (inode == NULL)
1720030 {
1720031 errset (ENOENT);
1720032 return (-1);
1720033 }
1720034 //
1720035 // Verify to be root, as the ability to change group
1720036 // is not taken into consideration.
1720037 //
1720038 if (ps->euid != 0)
1720039 {
1720040 errset (EACCES); // Permission denied.
1720041 return (-1);
1720042 }
1720043 //
1720044 // Update the ownership.
1720045 //
1720046 if (uid != -1)
1720047 {
1720048 inode->uid = uid;
1720049 inode->changed = 1;
1720050 }
1720051 if (gid != -1)
1720052 {
1720053 inode->gid = gid;
1720054 inode->changed = 1;
1720055 }
1720056 //
1720057 // Save the inode.
1720058 //
1720059 inode->changed = 1;
1720060 inode_save (inode);
1720061 //
1720062 // Return.
1720063 //
1720064 return (0);
1720065 }
|
|
94.8.15
kernel/lib_s/s_fcntl.c
Si veda la sezione 87.18.
1730001 #include <kernel/proc.h>
1730002 #include <kernel/lib_s.h>
1730003 #include <kernel/fs.h>
1730004 #include <errno.h>
1730005 #include <fcntl.h>
1730006 //----------------------------------------------------------
1730007 int
1730008 s_fcntl (pid_t pid, int fdn, int cmd, int arg)
1730009 {
1730010 proc_t *ps;
1730011 int mask;
1730012 //
1730013 // Get process.
1730014 //
1730015 ps = proc_reference (pid);
1730016 //
1730017 // Verify if the file descriptor is valid.
1730018 //
1730019 if (ps->fd[fdn].file == NULL)
1730020 {
1730021 errset (EBADF); // Bad file descriptor.
1730022 return (-1);
1730023 }
1730024 //
1730025 //
1730026 //
1730027 switch (cmd)
1730028 {
1730029 case F_DUPFD:
1730030 return (fd_dup (pid, fdn, arg));
1730031 break;
1730032 case F_GETFD:
1730033 return (ps->fd[fdn].fd_flags);
1730034 break;
1730035 case F_SETFD:
1730036 ps->fd[fdn].fd_flags = arg;
1730037 return (0);
1730038 case F_GETFL:
1730039 return (ps->fd[fdn].fl_flags);
1730040 case F_SETFL:
1730041 //
1730042 // Calculate a mask with bits that are *not* to
1730043 // be set.
1730044 //
1730045 mask =
1730046 (O_ACCMODE | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1730047 //
1730048 // Set to zero the bits that are not to be set
1730049 // from
1730050 // the argument.
1730051 //
1730052 arg = (arg & ~mask);
1730053 //
1730054 // Set to zero the bit that *are* to be set.
1730055 //
1730056 ps->fd[fdn].fl_flags &= mask;
1730057 //
1730058 // Set the bits, already filtered inside the
1730059 // argument.
1730060 //
1730061 ps->fd[fdn].fl_flags |= arg;
1730062 //
1730063 return (0);
1730064 default:
1730065 errset (EINVAL); // Not implemented.
1730066 return (-1);
1730067 }
1730068 }
|
|
94.8.16
kernel/lib_s/s_fork.c
Si veda la sezione 87.19.
1740001 #include <kernel/proc.h>
1740002 #include <errno.h>
1740003 #include <fcntl.h>
1740004 #include <kernel/lib_k.h>
1740005 #include <kernel/lib_s.h>
1740006 //----------------------------------------------------------
1740007 #define DEBUG 0
1740008 //----------------------------------------------------------
1740009 extern uint32_t proc_stack_pointer;
1740010 //----------------------------------------------------------
1740011 pid_t
1740012 s_fork (pid_t ppid)
1740013 {
1740014 pid_t pid;
1740015 pid_t zombie;
1740016 addr_t allocated_text = 0;
1740017 addr_t allocated_data = 0;
1740018 addr_t addr_stack_pointer = 0;
1740019 int fdn;
1740020 uint16_t segment_descriptor;
1740021 int sig;
1740022 //
1740023 // Find a free PID.
1740024 //
1740025 for (pid = 1; pid < PROCESS_MAX; pid++)
1740026 {
1740027 if (proc_table[pid].status == PROC_EMPTY)
1740028 {
1740029 break;
1740030 }
1740031 }
1740032 if (pid >= PROCESS_MAX)
1740033 {
1740034 //
1740035 // There is no free pid.
1740036 //
1740037 errset (ENOMEM); // Not enough space.
1740038 return (-1);
1740039 }
1740040 //
1740041 // Before allocating a new process, must check if
1740042 // there are some
1740043 // zombie slots, still with original segment data:
1740044 // should reset
1740045 // them now!
1740046 //
1740047 for (zombie = 1; zombie < PROCESS_MAX; zombie++)
1740048 {
1740049 if (proc_table[zombie].status == PROC_ZOMBIE
1740050 && (proc_table[zombie].address_text != 0
1740051 || proc_table[zombie].domain_text != 0))
1740052 {
1740053 proc_table[zombie].address_text = (addr_t) 0;
1740054 proc_table[zombie].domain_text = (size_t) 0;
1740055 proc_table[zombie].address_data = (addr_t) 0;
1740056 proc_table[zombie].domain_data = (size_t) 0;
1740057 proc_table[zombie].domain_stack = (size_t) 0;
1740058 proc_table[zombie].extra_data = (size_t) 0;
1740059 proc_table[zombie].sp = 0;
1740060 }
1740061 }
1740062 //
1740063 // Allocate memory for text, if text and data are
1740064 // inside
1740065 // the same address space.
1740066 //
1740067 if (proc_table[ppid].domain_data == 0)
1740068 {
1740069 allocated_text =
1740070 mb_alloc_size (proc_table[ppid].domain_text +
1740071 proc_table[ppid].extra_data);
1740072 //
1740073 if (allocated_text == 0)
1740074 {
1740075 errset (ENOMEM); // Not enough space.
1740076 return ((pid_t) - 1);
1740077 }
1740078 //
1740079 if (DEBUG)
1740080 {
1740081 k_printf ("%s:%i:mb_alloc_size(%zi)",
1740082 __FILE__, __LINE__,
1740083 (proc_table[ppid].domain_text
1740084 + proc_table[ppid].extra_data));
1740085 }
1740086 }
1740087 //
1740088 // Allocate memory for data, if necessary.
1740089 //
1740090 if (proc_table[ppid].domain_data > 0)
1740091 {
1740092 allocated_data =
1740093 mb_alloc_size (proc_table[ppid].domain_data +
1740094 proc_table[ppid].extra_data);
1740095 //
1740096 if (allocated_data == 0)
1740097 {
1740098 //
1740099 // Please note that, if we are here, no
1740100 // memory
1740101 // for the text was allocated!
1740102 //
1740103 errset (ENOMEM); // Not enough space.
1740104 return ((pid_t) - 1);
1740105 }
1740106 //
1740107 if (DEBUG)
1740108 {
1740109 k_printf ("%s:%i:mb_alloc_size(%zi)",
1740110 __FILE__, __LINE__,
1740111 (proc_table[ppid].domain_data
1740112 + proc_table[ppid].extra_data));
1740113 }
1740114 }
1740115 //
1740116 // Copy the process text and, data in memory: if
1740117 // size is zero, no copy is made. But the text is
1740118 // copied only if text and data live together.
1740119 //
1740120 if (proc_table[ppid].domain_data == 0)
1740121 {
1740122 memcpy ((void *) allocated_text,
1740123 (void *) proc_table[ppid].address_text,
1740124 (size_t) (proc_table[ppid].domain_text
1740125 + proc_table[ppid].extra_data));
1740126 }
1740127 else
1740128 {
1740129 memcpy ((void *) allocated_data,
1740130 (void *) proc_table[ppid].address_data,
1740131 (size_t) (proc_table[ppid].domain_data
1740132 + proc_table[ppid].extra_data));
1740133 }
1740134 //
1740135 // Allocate the new PID inside the `proc_table[]'.
1740136 //
1740137 proc_table[pid].ppid = ppid;
1740138 proc_table[pid].pgrp = proc_table[ppid].pgrp;
1740139 proc_table[pid].uid = proc_table[ppid].uid;
1740140 proc_table[pid].euid = proc_table[ppid].euid;
1740141 proc_table[pid].suid = proc_table[ppid].suid;
1740142 proc_table[pid].gid = proc_table[ppid].gid;
1740143 proc_table[pid].egid = proc_table[ppid].egid;
1740144 proc_table[pid].sgid = proc_table[ppid].sgid;
1740145 proc_table[pid].device_tty = proc_table[ppid].device_tty;
1740146 proc_table[pid].sig_status = 0;
1740147 proc_table[pid].sig_ignore = 0;
1740148 //
1740149 for (sig = 0; sig < MAX_SIGNALS; sig++)
1740150 {
1740151 proc_table[pid].sig_handler[sig]
1740152 = proc_table[ppid].sig_handler[sig];
1740153 }
1740154 //
1740155 proc_table[pid].usage = 0;
1740156 proc_table[pid].status = PROC_CREATED;
1740157 proc_table[pid].wakeup_events = 0;
1740158 proc_table[pid].wakeup_signal = 0;
1740159 proc_table[pid].wakeup_timer = 0;
1740160 //
1740161 if (proc_table[ppid].domain_data != 0)
1740162 {
1740163 proc_table[pid].address_text =
1740164 proc_table[ppid].address_text;
1740165 }
1740166 else
1740167 {
1740168 proc_table[pid].address_text = allocated_text;
1740169 }
1740170 proc_table[pid].domain_text =
1740171 proc_table[ppid].domain_text;
1740172 proc_table[pid].address_data = allocated_data;
1740173 proc_table[pid].domain_data =
1740174 proc_table[ppid].domain_data;
1740175 proc_table[pid].domain_stack =
1740176 proc_table[ppid].domain_stack;
1740177 proc_table[pid].extra_data = proc_table[ppid].extra_data;
1740178 proc_table[pid].sp = proc_stack_pointer;
1740179 proc_table[pid].ret = 0;
1740180 proc_table[pid].inode_cwd = proc_table[ppid].inode_cwd;
1740181 proc_table[pid].umask = proc_table[ppid].umask;
1740182 strncpy (proc_table[pid].name, proc_table[ppid].name,
1740183 PATH_MAX);
1740184 strncpy (proc_table[pid].path_cwd,
1740185 proc_table[ppid].path_cwd, PATH_MAX);
1740186 //
1740187 // Update process TEXT segment inside the GDT table.
1740188 //
1740189 gdt_segment (gdt_pid_to_segment_text (pid),
1740190 (uint32_t) proc_table[pid].address_text,
1740191 (uint32_t) (proc_table[pid].domain_text /
1740192 4096), 1, 1, 0);
1740193 //
1740194 // Update process DATA segment inside the GDT table.
1740195 //
1740196 if (proc_table[pid].domain_data > 0)
1740197 {
1740198 gdt_segment (gdt_pid_to_segment_data (pid),
1740199 (uint32_t) proc_table[pid].address_data,
1740200 (uint32_t) ((proc_table[pid].domain_data
1740201 +
1740202 proc_table[pid].extra_data)
1740203 / 4096), 1, 0, 0);
1740204 }
1740205 else
1740206 {
1740207 gdt_segment (gdt_pid_to_segment_data (pid),
1740208 (uint32_t) proc_table[pid].address_text,
1740209 (uint32_t) ((proc_table[pid].domain_text
1740210 +
1740211 proc_table[pid].extra_data)
1740212 / 4096), 1, 0, 0);
1740213 }
1740214 //
1740215 // -------------------------------------------------
1740216 // Might reload the GDT table, but it is not
1740217 // necessarily.
1740218 // Anyway, if you do it, nothing change. :-)
1740219 //
1740220 // gdt_load (&gdt_register);
1740221 // -------------------------------------------------
1740222 //
1740223 // Increase inode references for the working
1740224 // directory.
1740225 //
1740226 proc_table[pid].inode_cwd->references++;
1740227 //
1740228 // Duplicate valid file descriptors.
1740229 //
1740230 for (fdn = 0; fdn < OPEN_MAX; fdn++)
1740231 {
1740232 if (proc_table[ppid].fd[fdn].file != NULL
1740233 && (proc_table[ppid].fd[fdn].file->inode !=
1740234 NULL
1740235 || proc_table[ppid].fd[fdn].file->sock !=
1740236 NULL))
1740237 {
1740238 //
1740239 // Copy to the forked process.
1740240 //
1740241 proc_table[pid].fd[fdn].fl_flags
1740242 = proc_table[ppid].fd[fdn].fl_flags;
1740243 proc_table[pid].fd[fdn].fd_flags
1740244 = proc_table[ppid].fd[fdn].fd_flags;
1740245 proc_table[pid].fd[fdn].file =
1740246 proc_table[ppid].fd[fdn].file;
1740247 //
1740248 // Increment file reference.
1740249 //
1740250 proc_table[ppid].fd[fdn].file->references++;
1740251 //
1740252 // Check if it is a pipe and increment
1740253 // specific
1740254 // read/write reference counters inside the
1740255 // inode.
1740256 //
1740257 if (proc_table[ppid].fd[fdn].file->inode !=
1740258 NULL
1740259 && S_ISFIFO (proc_table[ppid].fd[fdn].
1740260 file->inode->mode))
1740261 {
1740262 if (proc_table[ppid].fd[fdn].
1740263 fl_flags & O_RDONLY)
1740264 {
1740265 proc_table[ppid].fd[fdn].file->
1740266 inode->pipe_ref_read++;
1740267 }
1740268 //
1740269 if (proc_table[ppid].fd[fdn].
1740270 fl_flags & O_WRONLY)
1740271 {
1740272 proc_table[ppid].fd[fdn].file->
1740273 inode->pipe_ref_write++;
1740274 }
1740275 }
1740276 }
1740277 }
1740278 //
1740279 // Change segment descriptor values inside the
1740280 // stack,
1740281 // for: DS==ES==FS==GS.
1740282 //
1740283 // First calculate the absolute stack section
1740284 // address, from the
1740285 // kernel point of view.
1740286 //
1740287 if (allocated_data > 0)
1740288 {
1740289 addr_stack_pointer = allocated_data;
1740290 }
1740291 else
1740292 {
1740293 addr_stack_pointer = allocated_text;
1740294 }
1740295 //
1740296 // Then calculate the effective new stack pointer.
1740297 //
1740298 addr_stack_pointer += proc_table[pid].sp;
1740299 //
1740300 // Then calculate the segment descriptor, to be
1740301 // written
1740302 // inside the new process stack.
1740303 //
1740304 segment_descriptor = (gdt_pid_to_segment_data (pid) * 8);
1740305 //
1740306 // Then copy inside the stack the new values for
1740307 // data segments.
1740308 //
1740309 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
1740310 (addr_stack_pointer + 28),
1740311 &segment_descriptor,
1740312 (sizeof segment_descriptor), NULL);
1740313 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
1740314 (addr_stack_pointer + 32),
1740315 &segment_descriptor,
1740316 (sizeof segment_descriptor), NULL);
1740317 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
1740318 (addr_stack_pointer + 36),
1740319 &segment_descriptor,
1740320 (sizeof segment_descriptor), NULL);
1740321 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
1740322 (addr_stack_pointer + 40),
1740323 &segment_descriptor,
1740324 (sizeof segment_descriptor), NULL);
1740325 //
1740326 // Change segment descriptor value inside the stack
1740327 // for CS,
1740328 // if so is necessary.
1740329 //
1740330 segment_descriptor = (gdt_pid_to_segment_text (pid) * 8);
1740331 //
1740332 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
1740333 (addr_stack_pointer + 48),
1740334 &segment_descriptor,
1740335 (sizeof segment_descriptor), NULL);
1740336 //
1740337 // Set it ready.
1740338 //
1740339 proc_table[pid].status = PROC_READY;
1740340 //
1740341 // Return the new PID.
1740342 //
1740343 return (pid);
1740344 }
|
|
94.8.17
kernel/lib_s/s_fstat.c
Si veda la sezione 87.55.
1750001 #include <kernel/proc.h>
1750002 #include <kernel/lib_s.h>
1750003 #include <errno.h>
1750004 #include <fcntl.h>
1750005 //----------------------------------------------------------
1750006 int
1750007 s_fstat (pid_t pid, int fdn, struct stat *buffer)
1750008 {
1750009 proc_t *ps;
1750010 inode_t *inode;
1750011 //
1750012 // Get process.
1750013 //
1750014 ps = proc_reference (pid);
1750015 //
1750016 // Verify if the file descriptor is valid.
1750017 //
1750018 if (ps->fd[fdn].file == NULL)
1750019 {
1750020 errset (EBADF); // Bad file descriptor.
1750021 return (-1);
1750022 }
1750023 //
1750024 // Reach the inode.
1750025 //
1750026 inode = ps->fd[fdn].file->inode;
1750027 //
1750028 // If the Inode does not exist, exit with error.
1750029 //
1750030 if (inode == NULL)
1750031 {
1750032 errset (ENOENT);
1750033 return (-1);
1750034 }
1750035 //
1750036 // Inode loaded: update the buffer.
1750037 //
1750038 buffer->st_dev = inode->sb->device;
1750039 buffer->st_ino = inode->ino;
1750040 buffer->st_mode = inode->mode;
1750041 buffer->st_nlink = inode->links;
1750042 buffer->st_uid = inode->uid;
1750043 buffer->st_gid = inode->gid;
1750044 if (S_ISBLK (buffer->st_mode)
1750045 || S_ISCHR (buffer->st_mode))
1750046 {
1750047 buffer->st_rdev = inode->direct[0];
1750048 }
1750049 else
1750050 {
1750051 buffer->st_rdev = 0;
1750052 }
1750053 buffer->st_size = inode->size;
1750054 buffer->st_atime = inode->time; // All times
1750055 // are the
1750056 // same for
1750057 buffer->st_mtime = inode->time; // Minix 1
1750058 // file
1750059 // system.
1750060 buffer->st_ctime = inode->time; //
1750061 buffer->st_blksize = inode->sb->blksize;
1750062 buffer->st_blocks = inode->blkcnt;
1750063 //
1750064 // If the inode is a device special file, the
1750065 // `st_rdev' value is
1750066 // taken from the first direct zone (as of Minix 1
1750067 // organization).
1750068 //
1750069 if (S_ISBLK (inode->mode) || S_ISCHR (inode->mode))
1750070 {
1750071 buffer->st_rdev = inode->direct[0];
1750072 }
1750073 else
1750074 {
1750075 buffer->st_rdev = 0;
1750076 }
1750077 //
1750078 // Return.
1750079 //
1750080 return (0);
1750081 }
|
|
94.8.18
kernel/lib_s/s_ipconfig.c
Si veda la sezione 87.28.
1760001 #include <kernel/net.h>
1760002 #include <kernel/net/route.h>
1760003 #include <kernel/net/arp.h>
1760004 #include <errno.h>
1760005 #include <kernel/proc.h>
1760006 //----------------------------------------------------------
1760007 // This syscall is present only inside os32.
1760008 //----------------------------------------------------------
1760009 int
1760010 s_ipconfig (pid_t pid, int n, in_addr_t addr, int m)
1760011 {
1760012 //
1760013 // Must be a privileged process.
1760014 //
1760015 if (proc_table[pid].euid != 0)
1760016 {
1760017 errset (EPERM);
1760018 return (-1);
1760019 }
1760020 //
1760021 // Check arguments: net0 cannot be modified, because
1760022 // it is necessarily
1760023 // assigned to the loopback virtual interface.
1760024 //
1760025 if (n > NET_MAX_DEVICES || n < 1)
1760026 {
1760027 errset (EINVAL);
1760028 return (-1);
1760029 }
1760030 if (m > 32 || n < 0)
1760031 {
1760032 errset (EINVAL);
1760033 return (-1);
1760034 }
1760035 //
1760036 // Verify that the interface is present.
1760037 //
1760038 if (net_table[n].type == NET_DEV_NULL)
1760039 {
1760040 errset (ENODEV);
1760041 return (-1);
1760042 }
1760043 //
1760044 // Remove previous route related to the interface,
1760045 // if the interface
1760046 // was already configured.
1760047 //
1760048 if (net_table[n].ip != 0 && net_table[n].m != 0)
1760049 {
1760050 s_routedel (pid, net_table[n].ip, net_table[n].m);
1760051 }
1760052 //
1760053 // Modify the net_table[].
1760054 //
1760055 net_table[n].ip = ntohl (addr);
1760056 net_table[n].m = m;
1760057 //
1760058 // Add the route.
1760059 //
1760060 if (net_table[n].ip != 0 && net_table[n].m != 0)
1760061 {
1760062 return (s_routeadd (pid, addr, m, 0, n));
1760063 }
1760064 //
1760065 return (0);
1760066 }
|
|
94.8.19
kernel/lib_s/s_kill.c
Si veda la sezione 87.29.
1770001 #include <kernel/proc.h>
1770002 #include <kernel/lib_s.h>
1770003 #include <errno.h>
1770004 //----------------------------------------------------------
1770005 int
1770006 s_kill (pid_t pid_killer, pid_t pid_target, int sig)
1770007 {
1770008 uid_t euid = proc_table[pid_killer].euid;
1770009 uid_t uid = proc_table[pid_killer].uid;
1770010 pid_t pgrp = proc_table[pid_killer].pgrp;
1770011 int p; // Index inside the process table.
1770012 //
1770013 if (pid_target < -1)
1770014 {
1770015 errset (ESRCH);
1770016 return (-1);
1770017 }
1770018 else if (pid_target == -1)
1770019 {
1770020 if (sig == 0)
1770021 {
1770022 return (0);
1770023 }
1770024 if (euid == 0)
1770025 {
1770026 //
1770027 // Because `pid_target' is qual to `-1' and
1770028 // the effective
1770029 // user identity is `0', then, all
1770030 // processes,
1770031 // except the kernel and init, will receive
1770032 // the signal.
1770033 //
1770034 // The following scan starts from 2, to
1770035 // preserve the
1770036 // kernel and init processes.
1770037 //
1770038 for (p = 2; p < PROCESS_MAX; p++)
1770039 {
1770040 if (proc_table[p].status != PROC_EMPTY
1770041 && proc_table[p].status != PROC_ZOMBIE)
1770042 {
1770043 proc_sig_on (p, sig);
1770044 }
1770045 }
1770046 }
1770047 else
1770048 {
1770049 //
1770050 // Because `pid_target' is qual to `-1', but
1770051 // the effective
1770052 // user identity is not `0', then, all
1770053 // processes owned
1770054 // by the same effective user identity, will
1770055 // receive the
1770056 // signal.
1770057 //
1770058 // The following scan starts from 1, to
1770059 // preserve the
1770060 // kernel process.
1770061 //
1770062 for (p = 1; p < PROCESS_MAX; p++)
1770063 {
1770064 if (proc_table[p].status != PROC_EMPTY
1770065 && proc_table[p].status !=
1770066 PROC_ZOMBIE && proc_table[p].uid == euid)
1770067 {
1770068 proc_sig_on (p, sig);
1770069 }
1770070 }
1770071 }
1770072 return (0);
1770073 }
1770074 else if (pid_target == 0)
1770075 {
1770076 if (sig == 0)
1770077 {
1770078 return (0);
1770079 }
1770080 //
1770081 // The following scan starts from 1, to preserve
1770082 // the
1770083 // kernel process.
1770084 //
1770085 for (p = 1; p < PROCESS_MAX; p++)
1770086 {
1770087 if (proc_table[p].status != PROC_EMPTY
1770088 && proc_table[p].status != PROC_ZOMBIE
1770089 && proc_table[p].pgrp == pgrp)
1770090 {
1770091 proc_sig_on (p, sig);
1770092 }
1770093 }
1770094 return (0);
1770095 }
1770096 else if (pid_target >= PROCESS_MAX)
1770097 {
1770098 errset (ESRCH);
1770099 return (-1);
1770100 }
1770101 else // (pid_target > 0)
1770102 {
1770103 if (proc_table[pid_target].status == PROC_EMPTY
1770104 || proc_table[pid_target].status == PROC_ZOMBIE)
1770105 {
1770106 errset (ESRCH);
1770107 return (-1);
1770108 }
1770109 else if (uid == proc_table[pid_target].uid ||
1770110 uid == proc_table[pid_target].suid ||
1770111 euid == proc_table[pid_target].uid ||
1770112 euid == proc_table[pid_target].suid
1770113 || euid == 0)
1770114 {
1770115 if (sig == 0)
1770116 {
1770117 return (0);
1770118 }
1770119 else
1770120 {
1770121 proc_sig_on (pid_target, sig);
1770122 return (0);
1770123 }
1770124 }
1770125 else
1770126 {
1770127 errset (EPERM);
1770128 return (-1);
1770129 }
1770130 }
1770131 }
|
|
94.8.20
kernel/lib_s/s_link.c
Si veda la sezione 87.30.
1780001 #include <kernel/fs.h>
1780002 #include <errno.h>
1780003 #include <kernel/proc.h>
1780004 #include <kernel/lib_s.h>
1780005 //----------------------------------------------------------
1780006 int
1780007 s_link (pid_t pid, const char *path_old,
1780008 const char *path_new)
1780009 {
1780010 proc_t *ps;
1780011 inode_t *inode_old;
1780012 inode_t *inode_new;
1780013 char path_new_full[PATH_MAX];
1780014 //
1780015 // Get process.
1780016 //
1780017 ps = proc_reference (pid);
1780018 //
1780019 // Try to get the old path inode.
1780020 //
1780021 inode_old = path_inode (pid, path_old);
1780022 if (inode_old == NULL)
1780023 {
1780024 //
1780025 // Cannot get the inode: `errno' is already set
1780026 // by
1780027 // `path_inode()'.
1780028 //
1780029 errset (errno);
1780030 return (-1);
1780031 }
1780032 //
1780033 // The inode is available and checks are done:
1780034 // arrange to get a
1780035 // packed full path name and then the destination
1780036 // directory path.
1780037 //
1780038 path_full (path_new, ps->path_cwd, path_new_full);
1780039 //
1780040 //
1780041 //
1780042 inode_new =
1780043 path_inode_link (pid, path_new_full, inode_old,
1780044 (mode_t) 0);
1780045 if (inode_new == NULL)
1780046 {
1780047 inode_put (inode_old);
1780048 return (-1);
1780049 }
1780050 if (inode_new != inode_old)
1780051 {
1780052 inode_put (inode_new);
1780053 inode_put (inode_old);
1780054 errset (EUNKNOWN); // Unknown error.
1780055 return (-1);
1780056 }
1780057 //
1780058 // Inode data is already updated by
1780059 // `path_inode_link()': just put
1780060 // it and return. Please note that only one is put,
1780061 // because it is
1780062 // just the same of the other.
1780063 //
1780064 inode_put (inode_new);
1780065 return (0);
1780066 }
|
|
94.8.21
kernel/lib_s/s_listen.c
Si veda la sezione 87.31.
1790001 #include <kernel/proc.h>
1790002 #include <kernel/lib_s.h>
1790003 #include <kernel/lib_k.h>
1790004 #include <errno.h>
1790005 #include <fcntl.h>
1790006 #include <sys/socket.h>
1790007 #include <arpa/inet.h>
1790008 //----------------------------------------------------------
1790009 int
1790010 s_listen (pid_t pid, int sfdn, int backlog)
1790011 {
1790012 fd_t *sfd;
1790013 int s;
1790014 //
1790015 // Get file descriptor and verify that it is a
1790016 // socket.
1790017 //
1790018 sfd = fd_reference (pid, &sfdn);
1790019 if (sfd == NULL || sfd->file == NULL)
1790020 {
1790021 errset (EBADF); // Bad file descriptor.
1790022 return (-1);
1790023 }
1790024 if (sfd->file->sock == NULL)
1790025 {
1790026 errset (ENOTSOCK); // Not a socket.
1790027 return (-1);
1790028 }
1790029 if (sfd->file->sock->type != SOCK_STREAM)
1790030 {
1790031 errset (EOPNOTSUPP); // Not a stream
1790032 // socket.
1790033 return (-1);
1790034 }
1790035 if (sfd->file->sock->raddr != 0
1790036 || sfd->file->sock->rport != 0)
1790037 {
1790038 //
1790039 // The socket is connected, and cannot be good
1790040 // for
1790041 // listening.
1790042 //
1790043 errset (EISCONN);
1790044 return (-1);
1790045 }
1790046 //
1790047 // Scan the other sockets to find if there is
1790048 // another one listening.
1790049 //
1790050 for (s = 0; s < SOCK_MAX_SLOTS; s++)
1790051 {
1790052 if (sock_table[s].tcp.conn == TCP_LISTEN
1790053 && sock_table[s].lport == sfd->file->sock->lport)
1790054 {
1790055 //
1790056 // Yes, there is one: sorry.
1790057 //
1790058 errset (EADDRINUSE);
1790059 return (-1);
1790060 }
1790061 }
1790062 //
1790063 // Check the current TCP state.
1790064 //
1790065 if (sfd->file->sock->tcp.conn != 0
1790066 && sfd->file->sock->tcp.conn != TCP_LISTEN)
1790067 {
1790068 //
1790069 // Cannot change the socket stream state.
1790070 //
1790071 errset (EISCONN);
1790072 return (-1);
1790073 }
1790074 //
1790075 // The socket might be already listening, but the
1790076 // newly requested
1790077 // queue should be greater or equal to the previous
1790078 // one.
1790079 //
1790080 if (sfd->file->sock->tcp.conn == TCP_LISTEN
1790081 && backlog < sfd->file->sock->tcp.listen_max)
1790082 {
1790083 //
1790084 // Cannot reduce the listen queue: just ignore.
1790085 //
1790086 return (0);
1790087 }
1790088 //
1790089 // Ok.
1790090 //
1790091 sfd->file->sock->tcp.conn = TCP_LISTEN;
1790092 sfd->file->sock->tcp.listen_max =
1790093 min (backlog, SOCK_MAX_QUEUE);
1790094 sfd->file->sock->tcp.listen_pid = pid;
1790095 return (0);
1790096 }
|
|
94.8.22
kernel/lib_s/s_longjmp.c
Si veda la sezione 87.49.
1800001 #include <kernel/lib_s.h>
1800002 #include <kernel/proc.h>
1800003 #include <errno.h>
1800004 #include <sys/os32.h>
1800005 //----------------------------------------------------------
1800006 extern uint32_t proc_stack_pointer;
1800007 //----------------------------------------------------------
1800008 void
1800009 s_longjmp (pid_t pid, jmp_buf env, int val)
1800010 {
1800011 jmp_stack_t *sp;
1800012 jmp_env_t *jmpenv;
1800013 //
1800014 // Translate the pointer `env', to the kernel point
1800015 // of view.
1800016 //
1800017 jmpenv = ptr (pid, env);
1800018 //
1800019 // Find where *was* the process stack in memory,
1800020 // from the kernel point
1800021 // of view. Please notice that the current stack at
1800022 // `proc_stack_pointer' will be saved from the
1800023 // scheduler inside
1800024 // the process table. So, the replacement is made at
1800025 // the current
1800026 // stack position, and not inside the process table.
1800027 //
1800028 sp = ptr (pid, (void *) jmpenv->esp0);
1800029 //
1800030 // Restore the process stack.
1800031 //
1800032 sp->eax0 = jmpenv->eax0;
1800033 sp->ecx0 = jmpenv->ecx0;
1800034 sp->edx0 = jmpenv->edx0;
1800035 sp->ebx0 = jmpenv->ebx0;
1800036 sp->ebp0 = jmpenv->ebp0;
1800037 sp->esi0 = jmpenv->esi0;
1800038 sp->edi0 = jmpenv->edi0;
1800039 sp->ds0 = jmpenv->ds0;
1800040 sp->es0 = jmpenv->es0;
1800041 sp->fs0 = jmpenv->fs0;
1800042 sp->gs0 = jmpenv->gs0;
1800043 sp->eflags0 = jmpenv->eflags0;
1800044 sp->cs0 = jmpenv->cs0;
1800045 sp->eip0 = jmpenv->eip0;
1800046 //
1800047 sp->eip1 = jmpenv->eip1;
1800048 sp->syscallnr = jmpenv->syscallnr;
1800049 sp->msg_pointer = jmpenv->msg_pointer;
1800050 sp->msg_size = jmpenv->msg_size;
1800051 sp->env = jmpenv->env;
1800052 sp->ret = val;
1800053 sp->ebp1 = jmpenv->ebp1;
1800054 sp->eip2 = jmpenv->eip2;
1800055 //
1800056 // Replace the stack pointer too!
1800057 //
1800058 proc_stack_pointer = jmpenv->esp0;
1800059 }
|
|
94.8.23
kernel/lib_s/s_lseek.c
Si veda la sezione 87.33.
1810001 #include <kernel/proc.h>
1810002 #include <kernel/lib_s.h>
1810003 #include <errno.h>
1810004 //----------------------------------------------------------
1810005 off_t
1810006 s_lseek (pid_t pid, int fdn, off_t offset, int whence)
1810007 {
1810008 inode_t *inode;
1810009 file_t *file;
1810010 fd_t *fd;
1810011 off_t test_offset;
1810012 //
1810013 // Get file descriptor.
1810014 //
1810015 fd = fd_reference (pid, &fdn);
1810016 if (fd == NULL || fd->file == NULL
1810017 || fd->file->inode == NULL)
1810018 {
1810019 errset (EBADF); // Bad file descriptor.
1810020 return (-1);
1810021 }
1810022 //
1810023 // Get file table item.
1810024 //
1810025 file = fd->file;
1810026 //
1810027 // Get inode.
1810028 //
1810029 inode = file->inode;
1810030 //
1810031 // Change position depending on the `whence'
1810032 // parameter.
1810033 //
1810034 if (whence == SEEK_SET)
1810035 {
1810036 if (offset < 0)
1810037 {
1810038 errset (EINVAL); // Invalid argument.
1810039 return ((off_t) - 1);
1810040 }
1810041 else
1810042 {
1810043 fd->file->offset = offset;
1810044 }
1810045 }
1810046 else if (whence == SEEK_CUR)
1810047 {
1810048 test_offset = fd->file->offset;
1810049 test_offset += offset;
1810050 if (test_offset < 0)
1810051 {
1810052 errset (EINVAL); // Invalid argument.
1810053 return ((off_t) - 1);
1810054 }
1810055 else
1810056 {
1810057 fd->file->offset = test_offset;
1810058 }
1810059 }
1810060 else if (whence == SEEK_END)
1810061 {
1810062 test_offset = inode->size;
1810063 test_offset += offset;
1810064 if (test_offset < 0)
1810065 {
1810066 errset (EINVAL); // Invalid argument.
1810067 return ((off_t) - 1);
1810068 }
1810069 else
1810070 {
1810071 fd->file->offset = test_offset;
1810072 }
1810073 }
1810074 else
1810075 {
1810076 errset (EINVAL); // Invalid argument.
1810077 return ((off_t) - 1);
1810078 }
1810079 //
1810080 // Return the new file position.
1810081 //
1810082 return (fd->file->offset);
1810083 }
|
|
94.8.24
kernel/lib_s/s_mkdir.c
Si veda la sezione 87.34.
1820001 #include <kernel/fs.h>
1820002 #include <errno.h>
1820003 #include <kernel/proc.h>
1820004 #include <libgen.h>
1820005 #include <kernel/lib_s.h>
1820006 //----------------------------------------------------------
1820007 int
1820008 s_mkdir (pid_t pid, const char *path, mode_t mode)
1820009 {
1820010 proc_t *ps;
1820011 inode_t *inode_directory;
1820012 inode_t *inode_parent;
1820013 int status;
1820014 char path_directory[PATH_MAX];
1820015 char path_copy[PATH_MAX];
1820016 char *path_parent;
1820017 ssize_t size_written;
1820018 //
1820019 struct
1820020 {
1820021 ino_t ino_1;
1820022 char name_1[NAME_MAX];
1820023 ino_t ino_2;
1820024 char name_2[NAME_MAX];
1820025 } directory;
1820026 //
1820027 // Get process.
1820028 //
1820029 ps = proc_reference (pid);
1820030 //
1820031 // Correct the mode with the umask.
1820032 //
1820033 mode &= ~ps->umask;
1820034 //
1820035 // Inside `mode', the file type is fixed. No check
1820036 // is made.
1820037 //
1820038 mode &= 00777;
1820039 mode |= S_IFDIR;
1820040 //
1820041 // The full path and the directory path is needed.
1820042 //
1820043 status = path_full (path, ps->path_cwd, path_directory);
1820044 if (status < 0)
1820045 {
1820046 return (-1);
1820047 }
1820048 strncpy (path_copy, path_directory, PATH_MAX);
1820049 path_copy[PATH_MAX - 1] = 0;
1820050 path_parent = dirname (path_copy);
1820051 //
1820052 // Check if something already exists with the same
1820053 // name. The scan
1820054 // is done with kernel privileges.
1820055 //
1820056 inode_directory = path_inode ((uid_t) 0, path_directory);
1820057 if (inode_directory != NULL)
1820058 {
1820059 //
1820060 // The file already exists. Put inode and return
1820061 // an error.
1820062 //
1820063 inode_put (inode_directory);
1820064 errset (EEXIST); // File exists.
1820065 return (-1);
1820066 }
1820067 //
1820068 // Try to locate the directory that should contain
1820069 // this one.
1820070 //
1820071 inode_parent = path_inode (pid, path_parent);
1820072 if (inode_parent == NULL)
1820073 {
1820074 //
1820075 // Cannot locate the directory: return an error.
1820076 // The variable
1820077 // `errno' should already be set by
1820078 // `path_inode()'.
1820079 //
1820080 errset (errno);
1820081 return (-1);
1820082 }
1820083 //
1820084 // Try to create the node: should fail if the user
1820085 // does not have
1820086 // enough permissions.
1820087 //
1820088 inode_directory =
1820089 path_inode_link (pid, path_directory, NULL, mode);
1820090 if (inode_directory == NULL)
1820091 {
1820092 //
1820093 // Sorry: cannot create the inode! The variable
1820094 // `errno' should
1820095 // already be set by `path_inode_link()'.
1820096 //
1820097 errset (errno);
1820098 return (-1);
1820099 }
1820100 //
1820101 // Fill records for `.' and `..'.
1820102 //
1820103 directory.ino_1 = inode_directory->ino;
1820104 strncpy (directory.name_1, ".", (size_t) 3);
1820105 directory.ino_2 = inode_parent->ino;
1820106 strncpy (directory.name_2, "..", (size_t) 3);
1820107 //
1820108 // Write data.
1820109 //
1820110 size_written =
1820111 inode_file_write (inode_directory, (off_t) 0,
1820112 &directory, (sizeof directory));
1820113 if (size_written != (sizeof directory))
1820114 {
1820115 return (-1);
1820116 }
1820117 //
1820118 // Fix directory inode links.
1820119 //
1820120 inode_directory->links = 2;
1820121 inode_directory->time = s_time (pid, NULL);
1820122 inode_directory->changed = 1;
1820123 //
1820124 // Fix parent directory inode links.
1820125 //
1820126 inode_parent->links++;
1820127 inode_parent->time = s_time (pid, NULL);
1820128 inode_parent->changed = 1;
1820129 //
1820130 // Save and put the inodes.
1820131 //
1820132 inode_save (inode_parent);
1820133 inode_save (inode_directory);
1820134 inode_put (inode_parent);
1820135 inode_put (inode_directory);
1820136 //
1820137 // Return.
1820138 //
1820139 return (0);
1820140 }
|
|
94.8.25
kernel/lib_s/s_mknod.c
Si veda la sezione 87.35.
1830001 #include <kernel/fs.h>
1830002 #include <errno.h>
1830003 #include <kernel/proc.h>
1830004 #include <kernel/lib_s.h>
1830005 //----------------------------------------------------------
1830006 int
1830007 s_mknod (pid_t pid, const char *path, mode_t mode,
1830008 dev_t device)
1830009 {
1830010 proc_t *ps;
1830011 inode_t *inode;
1830012 char full_path[PATH_MAX];
1830013 //
1830014 // Get process.
1830015 //
1830016 ps = proc_reference (pid);
1830017 //
1830018 // Correct the mode with the umask.
1830019 //
1830020 mode &= ~ps->umask;
1830021 //
1830022 // Currently must be root, unless the type is a
1830023 // regular file,
1830024 // or a FIFO file.
1830025 //
1830026 if (!(S_ISFIFO (mode) || S_ISREG (mode)))
1830027 {
1830028 if (ps->uid != 0)
1830029 {
1830030 errset (EPERM); // Operation not
1830031 // permitted.
1830032 return (-1);
1830033 }
1830034 }
1830035 //
1830036 // Check the type of node requested.
1830037 //
1830038 if (!(S_ISBLK (mode) ||
1830039 S_ISCHR (mode) ||
1830040 S_ISREG (mode) || S_ISFIFO (mode)
1830041 || S_ISDIR (mode)))
1830042 {
1830043 errset (EINVAL); // Invalid argument.
1830044 return (-1);
1830045 }
1830046 //
1830047 // Check if something already exists with the same
1830048 // name.
1830049 //
1830050 inode = path_inode (pid, path);
1830051 if (inode != NULL)
1830052 {
1830053 //
1830054 // The file already exists. Put inode and return
1830055 // an error.
1830056 //
1830057 inode_put (inode);
1830058 errset (EEXIST); // File exists.
1830059 return (-1);
1830060 }
1830061 //
1830062 // Try to creat the node.
1830063 //
1830064 path_full (path, ps->path_cwd, full_path);
1830065 inode = path_inode_link (pid, full_path, NULL, mode);
1830066 if (inode == NULL)
1830067 {
1830068 //
1830069 // Sorry: cannot create the inode!
1830070 //
1830071 return (-1);
1830072 }
1830073 //
1830074 // Set the device number if necessary.
1830075 //
1830076 if (S_ISBLK (mode) || S_ISCHR (mode))
1830077 {
1830078 inode->direct[0] = device;
1830079 inode->changed = 1;
1830080 }
1830081 //
1830082 // Put the inode.
1830083 //
1830084 inode_put (inode);
1830085 //
1830086 // Return.
1830087 //
1830088 return (0);
1830089 }
|
|
94.8.26
kernel/lib_s/s_mount.c
Si veda la sezione 87.36.
1840001 #include <kernel/fs.h>
1840002 #include <errno.h>
1840003 #include <kernel/proc.h>
1840004 #include <kernel/lib_s.h>
1840005 //----------------------------------------------------------
1840006 int
1840007 s_mount (pid_t pid, const char *path_dev,
1840008 const char *path_mnt, int options)
1840009 {
1840010 proc_t *ps;
1840011 dev_t device; // Device to mount.
1840012 inode_t *inode_mnt; // Directory mount point.
1840013 void *pstatus;
1840014 //
1840015 // Get process.
1840016 //
1840017 ps = proc_reference (pid);
1840018 //
1840019 // Verify to be the super user.
1840020 //
1840021 if (ps->euid != 0)
1840022 {
1840023 errset (EPERM); // Operation not permitted.
1840024 return (-1);
1840025 }
1840026 //
1840027 device = path_device (pid, path_dev);
1840028 if (device < 0)
1840029 {
1840030 return (-1);
1840031 }
1840032 //
1840033 inode_mnt = path_inode (pid, path_mnt);
1840034 if (inode_mnt == NULL)
1840035 {
1840036 return (-1);
1840037 }
1840038 if (!S_ISDIR (inode_mnt->mode))
1840039 {
1840040 inode_put (inode_mnt);
1840041 errset (ENOTDIR); // Not a directory.
1840042 return (-1);
1840043 }
1840044 if (inode_mnt->sb_attached != NULL)
1840045 {
1840046 inode_put (inode_mnt);
1840047 errset (EBUSY); // Device or resource busy.
1840048 return (-1);
1840049 }
1840050 //
1840051 // All data is available.
1840052 //
1840053 pstatus = sb_mount (device, &inode_mnt, options);
1840054 if (pstatus == NULL)
1840055 {
1840056 inode_put (inode_mnt);
1840057 return (-1);
1840058 }
1840059 //
1840060 return (0);
1840061 }
|
|
94.8.27
kernel/lib_s/s_open.c
Si veda la sezione 87.37.
1850001 #include <kernel/proc.h>
1850002 #include <kernel/lib_s.h>
1850003 #include <kernel/lib_k.h>
1850004 #include <errno.h>
1850005 #include <fcntl.h>
1850006 //----------------------------------------------------------
1850007 int
1850008 s_open (pid_t pid, const char *path, int oflags,
1850009 mode_t mode)
1850010 {
1850011 inode_t *inode;
1850012 int status;
1850013 file_t *file;
1850014 fd_t *fd;
1850015 int fdn;
1850016 char full_path[PATH_MAX];
1850017 int perm;
1850018 tty_t *tty;
1850019 mode_t umask;
1850020 int errno_save;
1850021 //
1850022 // k_printf ("%s(%i, %s, %x, %05o)\n", __func__,
1850023 // (int) pid,
1850024 // path, oflags, (int) mode);
1850025 //
1850026 // Check path argument.
1850027 //
1850028 if (path == NULL || strlen (path) == 0)
1850029 {
1850030 errset (EINVAL); // Invalid argument.
1850031 return (-1);
1850032 }
1850033 //
1850034 // Correct the mode with the umask. As it is not a
1850035 // directory, to the
1850036 // mode are removed execution and sticky
1850037 // permissions.
1850038 //
1850039 umask = proc_table[pid].umask | 01111;
1850040 mode &= ~umask;
1850041 //
1850042 // Check open options.
1850043 //
1850044 if (oflags & O_WRONLY)
1850045 {
1850046 //
1850047 // The file is to be opened for write, or for
1850048 // read/write.
1850049 // Try to get inode.
1850050 //
1850051 inode = path_inode (pid, path);
1850052 if (inode == NULL)
1850053 {
1850054 //
1850055 // Cannot get the inode. See if there is the
1850056 // creation
1850057 // option.
1850058 //
1850059 if (oflags & O_CREAT)
1850060 {
1850061 //
1850062 // Try to create the missing inode: the
1850063 // file must be a
1850064 // regular one, so add the mode.
1850065 //
1850066 path_full (path,
1850067 proc_table[pid].path_cwd,
1850068 full_path);
1850069 inode =
1850070 path_inode_link (pid, full_path, NULL,
1850071 (mode | S_IFREG));
1850072 if (inode == NULL)
1850073 {
1850074 //
1850075 // Sorry: cannot create the inode!
1850076 // Variable `errno'
1850077 // is already set by
1850078 // `path_inode_link()'.
1850079 //
1850080 errset (errno);
1850081 return (-1);
1850082 }
1850083 }
1850084 else
1850085 {
1850086 //
1850087 // Cannot open the inode. Variable
1850088 // `errno'
1850089 // should be already set by
1850090 // `path_inode()'.
1850091 //
1850092 errset (errno);
1850093 return (-1);
1850094 }
1850095 }
1850096 //
1850097 // The inode was read or created: check if it
1850098 // must be
1850099 // truncated. It can be truncated only if it is
1850100 // a regular
1850101 // file.
1850102 //
1850103 if (oflags & O_TRUNC && inode->mode & S_IFREG)
1850104 {
1850105 //
1850106 // Truncate inode.
1850107 //
1850108 status = inode_truncate (inode);
1850109 if (status != 0)
1850110 {
1850111 //
1850112 // Cannot truncate the inode: release it
1850113 // and return.
1850114 // But this error should never happen,
1850115 // because the
1850116 // function `inode_truncate()' will not
1850117 // return any
1850118 // other value than zero.
1850119 //
1850120 errno_save = errno;
1850121 inode_put (inode);
1850122 errset (errno_save);
1850123 return (-1);
1850124 }
1850125 }
1850126 }
1850127 else
1850128 {
1850129 //
1850130 // The file is to be opened for read, but not
1850131 // for write.
1850132 // Try to get inode.
1850133 //
1850134 inode = path_inode (pid, path);
1850135 if (inode == NULL)
1850136 {
1850137 //
1850138 // Cannot open the file.
1850139 //
1850140 errset (errno);
1850141 return (-1);
1850142 }
1850143 }
1850144 //
1850145 // An inode was opened: check type and access
1850146 // permissions.
1850147 // All file types are good, even directories, as the
1850148 // type
1850149 // DIR is implemented through file descriptors.
1850150 //
1850151 perm = 0;
1850152 if (oflags & O_RDONLY)
1850153 perm |= 4;
1850154 if (oflags & O_WRONLY)
1850155 perm |= 2;
1850156 status =
1850157 inode_check (inode, S_IFMT, perm,
1850158 proc_table[pid].euid,
1850159 proc_table[pid].egid);
1850160 if (status != 0)
1850161 {
1850162 //
1850163 // The file type is not correct or the user does
1850164 // not have
1850165 // permissions.
1850166 //
1850167 return (-1);
1850168 }
1850169 //
1850170 // Allocate the file, inside the file table.
1850171 //
1850172 file = file_reference (-1);
1850173 if (file == NULL)
1850174 {
1850175 //
1850176 // Cannot allocate the file inside the file
1850177 // table: release the
1850178 // inode, update `errno' and return.
1850179 //
1850180 inode_put (inode);
1850181 errset (ENFILE); // Too many files open in
1850182 // system.
1850183 return (-1);
1850184 }
1850185 //
1850186 // Put some data inside the file item. Only options
1850187 // O_RDONLY and O_WRONLY are kept here, because the
1850188 // O_APPEND
1850189 // is saved inside the file descriptor table.
1850190 //
1850191 file->references = 1;
1850192 file->oflags = (oflags & (O_RDONLY | O_WRONLY));
1850193 file->inode = inode;
1850194 file->sock = NULL;
1850195 //
1850196 // Allocate the file descriptor: variable `fdn' will
1850197 // be modified
1850198 // by the call to `fd_reference()'.
1850199 //
1850200 fdn = -1;
1850201 fd = fd_reference (pid, &fdn);
1850202 if (fd == NULL)
1850203 {
1850204 //
1850205 // Cannot allocate the file descriptor: remove
1850206 // the item from
1850207 // file table.
1850208 //
1850209 file->references = 0;
1850210 file->oflags = 0;
1850211 file->inode = NULL;
1850212 file->sock = NULL;
1850213 //
1850214 // Release the inode.
1850215 //
1850216 inode_put (inode);
1850217 //
1850218 // Return an error.
1850219 //
1850220 errset (EMFILE); // Too many open files.
1850221 return (-1);
1850222 }
1850223 //
1850224 // File descriptor allocated: put some data inside
1850225 // the
1850226 // file descriptor item.
1850227 //
1850228 fd->fl_flags =
1850229 (oflags & (O_RDONLY | O_WRONLY | O_APPEND));
1850230 fd->fd_flags = 0;
1850231 fd->file = file;
1850232 fd->file->offset = 0;
1850233 //
1850234 // Check for particular types and situations.
1850235 //
1850236 if ((S_ISCHR (inode->mode))
1850237 && (oflags & O_RDONLY) && (oflags & O_WRONLY))
1850238 {
1850239 //
1850240 // The inode is a character special file
1850241 // (related to a character
1850242 // device), opened for read and write!
1850243 //
1850244 if ((inode->direct[0] & 0xFF00) ==
1850245 (DEV_CONSOLE_MAJOR << 8))
1850246 {
1850247 //
1850248 // It is a terminal (currently only consoles
1850249 // are possible).
1850250 // Get the tty reference.
1850251 //
1850252 tty = tty_reference ((dev_t) inode->direct[0]);
1850253 //
1850254 // Verify that the terminal is not already
1850255 // the controlling
1850256 // terminal of some process group.
1850257 //
1850258 if (tty->pgrp == 0)
1850259 {
1850260 //
1850261 // The terminal is free: verify if the
1850262 // current process
1850263 // needs a controlling terminal.
1850264 //
1850265 if (proc_table[pid].device_tty == 0
1850266 && proc_table[pid].pgrp == pid)
1850267 {
1850268 //
1850269 // It is a group leader with no
1850270 // controlling
1850271 // terminal: set the controlling
1850272 // terminal.
1850273 //
1850274 proc_table[pid].device_tty =
1850275 inode->direct[0];
1850276 tty->pgrp = proc_table[pid].pgrp;
1850277 }
1850278 }
1850279 }
1850280 }
1850281 else if (S_ISFIFO (inode->mode))
1850282 {
1850283 //
1850284 // It is FIFO (named pipe).
1850285 //
1850286 if ((oflags & O_ACCMODE) == O_RDWR)
1850287 {
1850288 inode->pipe_ref_read++;
1850289 inode->pipe_ref_write++;
1850290 }
1850291 else if (oflags & O_RDONLY)
1850292 {
1850293 inode->pipe_ref_read++;
1850294 //
1850295 // Go to sleep if there are no processes
1850296 // writing to the
1850297 // inode. Otherwise, wake them up.
1850298 //
1850299 if (inode->pipe_ref_write == 0)
1850300 {
1850301 proc_table[pid].status = PROC_SLEEPING;
1850302 proc_table[pid].ret = 0;
1850303 proc_table[pid].wakeup_inode = inode;
1850304 proc_table[pid].wakeup_events =
1850305 WAKEUP_EVENT_PIPE_READ;
1850306 }
1850307 else
1850308 {
1850309 proc_wakeup_pipe_write (inode);
1850310 }
1850311 }
1850312 else if (oflags & O_WRONLY)
1850313 {
1850314 inode->pipe_ref_write++;
1850315 //
1850316 // Go to sleep if there are no processes
1850317 // reading to the
1850318 // inode. Otherwise, wake them up.
1850319 //
1850320 if (inode->pipe_ref_read == 0)
1850321 {
1850322 proc_table[pid].status = PROC_SLEEPING;
1850323 proc_table[pid].ret = 0;
1850324 proc_table[pid].wakeup_inode = inode;
1850325 proc_table[pid].wakeup_events =
1850326 WAKEUP_EVENT_PIPE_WRITE;
1850327 }
1850328 else
1850329 {
1850330 proc_wakeup_pipe_read (inode);
1850331 }
1850332 }
1850333 }
1850334 //
1850335 // Return the file descriptor.
1850336 //
1850337 return (fdn);
1850338 }
|
|
94.8.28
kernel/lib_s/s_pipe.c
Si veda la sezione 87.38.
1860001 #include <kernel/proc.h>
1860002 #include <kernel/lib_s.h>
1860003 #include <kernel/lib_k.h>
1860004 #include <errno.h>
1860005 #include <fcntl.h>
1860006 //----------------------------------------------------------
1860007 int
1860008 s_pipe (pid_t pid, int pipefd[2])
1860009 {
1860010 file_t *file;
1860011 fd_t *fd_read;
1860012 fd_t *fd_write;
1860013 int fdn_read;
1860014 int fdn_write;
1860015 //
1860016 // Allocate the file inside the file table and the
1860017 // inode inside
1860018 // the inode table.
1860019 //
1860020 file = file_pipe_make ();
1860021 if (file == NULL)
1860022 {
1860023 errset (errno);
1860024 return (-1);
1860025 }
1860026 //
1860027 // Prepare file descriptor for read.
1860028 //
1860029 fdn_read = -1;
1860030 fd_read = fd_reference (pid, &fdn_read);
1860031 if (fd_read == NULL)
1860032 {
1860033 //
1860034 // Cannot allocate the file descriptor: remove
1860035 // the item from
1860036 // file table and put the relative inode.
1860037 //
1860038 file->references = 0;
1860039 file->oflags = 0;
1860040 inode_put (file->inode);
1860041 file->inode = NULL;
1860042 //
1860043 // Return an error.
1860044 //
1860045 errset (EMFILE); // Too many open files.
1860046 return (-1);
1860047 }
1860048 //
1860049 // File descriptor allocated: put some data inside
1860050 // the
1860051 // file descriptor item and increment the pipe
1860052 // references
1860053 // for read.
1860054 //
1860055 fd_read->fl_flags = O_RDONLY;
1860056 fd_read->fd_flags = 0;
1860057 fd_read->file = file;
1860058 fd_read->file->offset = 0;
1860059 fd_read->file->inode->pipe_ref_read++;
1860060 //
1860061 // Prepare file descriptor for write.
1860062 //
1860063 fdn_write = -1;
1860064 fd_write = fd_reference (pid, &fdn_write);
1860065 if (fd_write == NULL)
1860066 {
1860067 //
1860068 // Cannot allocate the file descriptor: remove
1860069 // the item from
1860070 // file table and put the relative inode.
1860071 //
1860072 file->references = 0;
1860073 file->oflags = 0;
1860074 inode_put (file->inode);
1860075 file->inode = NULL;
1860076 //
1860077 // Remove file descriptor for read.
1860078 //
1860079 fd_read->file->inode->pipe_ref_read--;
1860080 fd_read->fl_flags = 0;
1860081 fd_read->fd_flags = 0;
1860082 fd_read->file = NULL;
1860083 //
1860084 // Return an error.
1860085 //
1860086 errset (EMFILE); // Too many open files.
1860087 return (-1);
1860088 }
1860089 //
1860090 // File descriptor allocated: put some data inside
1860091 // the
1860092 // file descriptor item.
1860093 //
1860094 fd_write->fl_flags = O_WRONLY;
1860095 fd_write->fd_flags = 0;
1860096 fd_write->file = file;
1860097 fd_write->file->offset = 0;
1860098 fd_write->file->inode->pipe_ref_write++;
1860099 //
1860100 // Save file descriptor numbers inside the
1860101 // `pipefd[]' array.
1860102 //
1860103 pipefd[0] = fdn_read;
1860104 pipefd[1] = fdn_write;
1860105 //
1860106 // Ok.
1860107 //
1860108 return (0);
1860109 }
|
|
94.8.29
kernel/lib_s/s_read.c
Si veda la sezione 87.39.
1870001 #include <kernel/proc.h>
1870002 #include <kernel/lib_s.h>
1870003 #include <errno.h>
1870004 #include <fcntl.h>
1870005 //----------------------------------------------------------
1870006 #define DEBUG 0
1870007 //----------------------------------------------------------
1870008 ssize_t
1870009 s_read (pid_t pid, int fdn, void *buffer, size_t count)
1870010 {
1870011 fd_t *fd;
1870012 ssize_t size_read;
1870013 int eof = 0;
1870014 //
1870015 // Get file descriptor.
1870016 //
1870017 fd = fd_reference (pid, &fdn);
1870018 if (fd == NULL || fd->file == NULL
1870019 || (fd->file->inode == NULL
1870020 && fd->file->sock == NULL))
1870021 {
1870022 errset (EBADF); // Bad file descriptor.
1870023 return ((ssize_t) - 1);
1870024 }
1870025 //
1870026 // Check if it is opened for read.
1870027 //
1870028 if (!(fd->file->oflags & O_RDONLY))
1870029 {
1870030 //
1870031 // The file is not opened for read.
1870032 //
1870033 errset (EINVAL); // Invalid argument.
1870034 return ((ssize_t) - 1);
1870035 }
1870036 //
1870037 // Check the kind of file to be read and read it.
1870038 //
1870039 if (fd->file->sock != NULL)
1870040 {
1870041 //
1870042 // Read from the socket and return.
1870043 //
1870044 return (s_recvfrom
1870045 (pid, fdn, buffer, count, 0, NULL, NULL));
1870046 }
1870047 else if (S_ISBLK (fd->file->inode->mode)
1870048 || S_ISCHR (fd->file->inode->mode))
1870049 {
1870050 //
1870051 // A device is to be read.
1870052 //
1870053 size_read =
1870054 dev_io (pid,
1870055 (dev_t) fd->file->inode->direct[0],
1870056 DEV_READ, fd->file->offset, buffer,
1870057 count, &eof);
1870058 if (size_read < 0
1870059 && (errno == EAGAIN || errno == EWOULDBLOCK))
1870060 {
1870061 if (fd->fl_flags & O_NONBLOCK)
1870062 {
1870063 //
1870064 // Non blocking null read.
1870065 //
1870066 ;
1870067 }
1870068 else
1870069 {
1870070 //
1870071 // Null read: put the process to sleep.
1870072 //
1870073 proc_table[pid].status = PROC_SLEEPING;
1870074 proc_table[pid].ret = 0;
1870075 proc_table[pid].wakeup_events =
1870076 WAKEUP_EVENT_DEV_READ;
1870077 proc_table[pid].wakeup_dev =
1870078 fd->file->inode->direct[0];
1870079 if (DEBUG)
1870080 {
1870081 k_printf
1870082 ("[%s] PID %i goes to sleep "
1870083 "waiting to read from a "
1870084 "device.\n", __FILE__, pid);
1870085 }
1870086 }
1870087 }
1870088 }
1870089 else if (S_ISREG (fd->file->inode->mode))
1870090 {
1870091 //
1870092 // A regular file is to be read.
1870093 //
1870094 size_read =
1870095 inode_file_read (fd->file->inode,
1870096 fd->file->offset, buffer,
1870097 count, &eof);
1870098 }
1870099 else if (S_ISDIR (fd->file->inode->mode))
1870100 {
1870101 //
1870102 // A directory, is to be read.
1870103 //
1870104 size_read =
1870105 inode_file_read (fd->file->inode,
1870106 fd->file->offset, buffer,
1870107 count, &eof);
1870108 }
1870109 else if (S_ISFIFO (fd->file->inode->mode))
1870110 {
1870111 //
1870112 // A pipe, is to be read.
1870113 //
1870114 size_read =
1870115 inode_pipe_read (fd->file->inode, buffer,
1870116 count, &eof);
1870117 //
1870118 if (size_read == 0)
1870119 {
1870120 //
1870121 // Check what to do.
1870122 //
1870123 if (fd->file->inode->pipe_ref_write == 0)
1870124 {
1870125 //
1870126 // EOF, if it is a valid pointer, is
1870127 // already
1870128 // set by `inode_pipe_read()', if is
1870129 // time to
1870130 // set it.
1870131 //
1870132 // Wake up processes waiting to write.
1870133 //
1870134 proc_wakeup_pipe_write (fd->file->inode);
1870135 //
1870136 return (size_read);
1870137 }
1870138 else
1870139 {
1870140 //
1870141 // Go to sleep.
1870142 //
1870143 proc_table[pid].status = PROC_SLEEPING;
1870144 proc_table[pid].ret = 0;
1870145 proc_table[pid].wakeup_inode =
1870146 fd->file->inode;
1870147 proc_table[pid].wakeup_events =
1870148 WAKEUP_EVENT_PIPE_READ;
1870149 if (DEBUG)
1870150 {
1870151 k_printf
1870152 ("[%s] PID %i goes to sleep "
1870153 "waiting to read from a pipe.\n",
1870154 __FILE__, pid);
1870155 }
1870156 }
1870157 }
1870158 else
1870159 {
1870160 //
1870161 // Wake up processes waiting to write.
1870162 //
1870163 proc_wakeup_pipe_write (fd->file->inode);
1870164 }
1870165 }
1870166 else
1870167 {
1870168 //
1870169 // Unsupported file type.
1870170 //
1870171 errset (E_FILE_TYPE_UNSUPPORTED); // File type
1870172 // unsupported.
1870173 return ((ssize_t) - 1);
1870174 }
1870175 //
1870176 // Update the file descriptor internal offset, if
1870177 // there is an inode.
1870178 //
1870179 if (fd->file->inode != NULL && size_read > 0)
1870180 {
1870181 fd->file->offset += size_read;
1870182 }
1870183 //
1870184 // Return the size read, even if it is an error.
1870185 // Please notice
1870186 // that a size of zero might be related to an end of
1870187 // file, or
1870188 // just that the read should be retried. For the
1870189 // latter case,
1870190 // -1 is returned with error EAGAIN, so that the
1870191 // function
1870192 // `read()' can retry.
1870193 //
1870194 if (size_read == 0 && !eof)
1870195 {
1870196 errset (EAGAIN);
1870197 return (-1);
1870198 }
1870199 else
1870200 {
1870201 return (size_read);
1870202 }
1870203 }
|
|
94.8.30
kernel/lib_s/s_recvfrom.c
Si veda la sezione 87.40.
1880001 #include <fcntl.h>
1880002 #include <kernel/proc.h>
1880003 #include <kernel/net.h>
1880004 #include <kernel/net/route.h>
1880005 #include <errno.h>
1880006 #include <arpa/inet.h>
1880007 #include <sys/os32.h>
1880008 #include <netinet/udp.h>
1880009 //----------------------------------------------------------
1880010 #define DEBUG 0
1880011 //----------------------------------------------------------
1880012 ssize_t
1880013 s_recvfrom (pid_t pid, int sfdn, void *buffer,
1880014 size_t length, int flags,
1880015 struct sockaddr *addrfrom, socklen_t * addrlen)
1880016 {
1880017 fd_t *sfd;
1880018 int i; // IP table index.
1880019 size_t size_read;
1880020 struct udphdr *udp;
1880021 void *data;
1880022 struct sockaddr_in *addrfrom_in = (void *) addrfrom;
1880023 //
1880024 // Get file descriptor and verify that it is a
1880025 // socket.
1880026 //
1880027 sfd = fd_reference (pid, &sfdn);
1880028 if (sfd == NULL || sfd->file == NULL)
1880029 {
1880030 errset (EBADF); // Bad file descriptor.
1880031 return ((ssize_t) - 1);
1880032 }
1880033 if (sfd->file->sock == NULL)
1880034 {
1880035 errset (ENOTSOCK); // Not a socket.
1880036 return ((ssize_t) - 1);
1880037 }
1880038 //
1880039 // Verify to have a valid buffer pointer.
1880040 //
1880041 if (buffer == NULL)
1880042 {
1880043 errset (EINVAL);
1880044 return ((ssize_t) - 1);
1880045 }
1880046 //
1880047 //
1880048 //
1880049 if (sfd->file->sock->family == AF_INET)
1880050 {
1880051 //
1880052 // INET
1880053 //
1880054 // Should do some check here...
1880055 //
1880056 if (sfd->file->sock->type == SOCK_RAW)
1880057 {
1880058 //
1880059 // RAW
1880060 //
1880061 if (sfd->file->sock->protocol == IPPROTO_ICMP)
1880062 {
1880063 //
1880064 // ICMP
1880065 //
1880066 //
1880067 // Scan the ip_table[] to find an ICMP
1880068 // packet
1880069 // that was not already seen by the
1880070 // socket.
1880071 //
1880072 for (i = 0; i < IP_MAX_PACKETS; i++)
1880073 {
1880074 //
1880075 // Check the protocol.
1880076 //
1880077 if (ip_table[i].packet.header.protocol !=
1880078 IPPROTO_ICMP)
1880079 {
1880080 //
1880081 // It is not ICMP.
1880082 //
1880083 continue;
1880084 }
1880085 //
1880086 // Is the packet new for the socket?
1880087 //
1880088 // Please notice that the kernel
1880089 // might be interrupted
1880090 // also between clock tics; so,
1880091 // during a single clock
1880092 // time, a new packet might be
1880093 // reached.
1880094 //
1880095 if (ip_table[i].clock
1880096 < sfd->file->sock->read.clock[i])
1880097 {
1880098 //
1880099 // Already seen or packet too
1880100 // old.
1880101 //
1880102 continue;
1880103 }
1880104 //
1880105 // Verify the IP addresses.
1880106 //
1880107 if (ip_table[i].packet.header.daddr
1880108 != htonl (sfd->file->sock->laddr)
1880109 && sfd->file->sock->laddr != 0)
1880110 {
1880111 //
1880112 // The local address does not
1880113 // match, and it is
1880114 // not zero.
1880115 //
1880116 continue;
1880117 }
1880118 //
1880119 if (ip_table[i].packet.header.saddr
1880120 != htonl (sfd->file->sock->raddr))
1880121 {
1880122 //
1880123 // The remote address does not
1880124 // match, but
1880125 // if it is zero, we accept all.
1880126 //
1880127 if (sfd->file->sock->raddr == 0)
1880128 {
1880129 //
1880130 // Can accept the packet.
1880131 //
1880132 ;
1880133 }
1880134 else
1880135 {
1880136 continue;
1880137 }
1880138 }
1880139 //
1880140 // Packet accepted.
1880141 //
1880142 // This ICMP RAW packet is new for
1880143 // the
1880144 // socket: save the clock time, so
1880145 // that the
1880146 // same packet is not read again.
1880147 //
1880148 sfd->file->sock->read.clock[i]
1880149 = ip_table[i].clock;
1880150 //
1880151 // Copy the packet.
1880152 //
1880153 size_read
1880154 =
1880155 min (ntohs
1880156 (ip_table[i].packet.header.
1880157 tot_len), length);
1880158 //
1880159 memcpy (buffer,
1880160 ip_table[i].packet.octet,
1880161 size_read);
1880162 //
1880163 // Get the source address and
1880164 // return.
1880165 //
1880166 if (addrfrom != NULL && addrlen != NULL)
1880167 {
1880168 if (*addrlen >=
1880169 sizeof (struct sockaddr_in))
1880170 {
1880171 addrfrom_in->sin_family = AF_INET;
1880172 addrfrom_in->sin_port = 0;
1880173 addrfrom_in->sin_addr.s_addr
1880174 =
1880175 ip_table[i].packet.header.saddr;
1880176 }
1880177 *addrlen =
1880178 sizeof (struct sockaddr_in);
1880179 }
1880180 return ((ssize_t) size_read);
1880181 }
1880182 }
1880183 else
1880184 {
1880185 //
1880186 // Unsupported protocol.
1880187 //
1880188 errset (EPROTONOSUPPORT);
1880189 return ((ssize_t) - 1);
1880190 }
1880191 }
1880192 else if (sfd->file->sock->type == SOCK_DGRAM)
1880193 {
1880194 //
1880195 // DGRAM
1880196 //
1880197 if (sfd->file->sock->protocol == IPPROTO_UDP)
1880198 {
1880199 //
1880200 // UDP
1880201 //
1880202 // Scan the ip_table[] to find an UDP
1880203 // packet
1880204 // that was not already seen by the
1880205 // socket.
1880206 //
1880207 for (i = 0; i < IP_MAX_PACKETS; i++)
1880208 {
1880209 //
1880210 // Check the protocol.
1880211 //
1880212 if (ip_table[i].packet.header.protocol !=
1880213 IPPROTO_UDP)
1880214 {
1880215 //
1880216 // It is not UDP.
1880217 //
1880218 continue;
1880219 }
1880220 //
1880221 // Is the packet new for the socket?
1880222 //
1880223 // Please notice that the kernel
1880224 // might be interrupted
1880225 // also between clock tics; so,
1880226 // during a single clock
1880227 // time, a new packet might be
1880228 // reached.
1880229 //
1880230 if (ip_table[i].clock
1880231 < sfd->file->sock->read.clock[i])
1880232 {
1880233 //
1880234 // Already seen or packet too
1880235 // old.
1880236 //
1880237 continue;
1880238 }
1880239 //
1880240 // Verify the ports.
1880241 //
1880242 udp = (struct udphdr *)
1880243 &ip_table[i].packet.octet
1880244 [sizeof (struct iphdr)];
1880245 //
1880246 if (udp->dest == 0)
1880247 {
1880248 //
1880249 // Cannot accept packets for the
1880250 // port zero!
1880251 //
1880252 continue;
1880253 }
1880254 //
1880255 if (udp->dest !=
1880256 htons (sfd->file->sock->lport))
1880257 {
1880258 //
1880259 // The local port does not
1880260 // match!
1880261 //
1880262 continue;
1880263 }
1880264 //
1880265 if (udp->source !=
1880266 htons (sfd->file->sock->rport)
1880267 && sfd->file->sock->rport != 0)
1880268 {
1880269 //
1880270 // The remote port does not
1880271 // match, and is not
1880272 // zero.
1880273 //
1880274 continue;
1880275 }
1880276 //
1880277 // Verify the IP addresses.
1880278 //
1880279 if (ip_table[i].packet.header.daddr
1880280 != htonl (sfd->file->sock->laddr)
1880281 && sfd->file->sock->laddr != 0)
1880282 {
1880283 //
1880284 // The local address does not
1880285 // match, and is
1880286 // not zero.
1880287 //
1880288 continue;
1880289 }
1880290 //
1880291 if (ip_table[i].packet.header.saddr
1880292 != htonl (sfd->file->sock->raddr)
1880293 && sfd->file->sock->raddr != 0)
1880294 {
1880295 //
1880296 // The remote address does not
1880297 // match, and is
1880298 // not zero.
1880299 //
1880300 continue;
1880301 }
1880302 //
1880303 // The packet is accepted.
1880304 //
1880305 // This UDP packet is new for the
1880306 // socket:
1880307 // save the clock time, so that the
1880308 // same packet is not read again.
1880309 //
1880310 sfd->file->sock->read.clock[i]
1880311 = ip_table[i].clock;
1880312 //
1880313 // Check the right minimal size to
1880314 // be read, comparing
1880315 // the size of the IP packet, the
1880316 // size of the UDP
1880317 // packet and the size requested.
1880318 //
1880319 size_read =
1880320 ntohs (ip_table[i].packet.header.
1880321 tot_len) -
1880322 (ip_table[i].packet.header.ihl * 4) -
1880323 (sizeof (struct udphdr));
1880324 size_read =
1880325 min (size_read,
1880326 (udp->len -
1880327 sizeof (struct udphdr)));
1880328 size_read = min (size_read, length);
1880329 //
1880330 // Copy the data inside the UDP
1880331 // packet.
1880332 //
1880333 data =
1880334 (((uint8_t *) udp) +
1880335 sizeof (struct udphdr));
1880336 //
1880337 memcpy (buffer, data, size_read);
1880338 //
1880339 // Get the source address and
1880340 // return.
1880341 //
1880342 if (addrfrom != NULL && addrlen != NULL)
1880343 {
1880344 if (*addrlen >=
1880345 sizeof (struct sockaddr_in))
1880346 {
1880347 addrfrom_in->sin_family = AF_INET;
1880348 addrfrom_in->sin_port =
1880349 udp->source;
1880350 addrfrom_in->sin_addr.s_addr =
1880351 ip_table[i].packet.header.saddr;
1880352 }
1880353 *addrlen =
1880354 sizeof (struct sockaddr_in);
1880355 }
1880356 return ((ssize_t) size_read);
1880357 }
1880358 }
1880359 }
1880360 else if (sfd->file->sock->type == SOCK_STREAM)
1880361 {
1880362 //
1880363 // STREAM
1880364 //
1880365 if (sfd->file->sock->protocol == IPPROTO_TCP)
1880366 {
1880367 //
1880368 // TCP
1880369 //
1880370 // See if the read side of the stream
1880371 // was closed.
1880372 //
1880373 if (sfd->file->sock->tcp.recv_closed
1880374 || sfd->file->sock->tcp.conn == TCP_CLOSE)
1880375 {
1880376 //
1880377 // If the `recv_size' is zero, the
1880378 // stream
1880379 // is closed.
1880380 //
1880381 if (sfd->file->sock->tcp.recv_size
1880382 == 0
1880383 || sfd->file->sock->tcp.can_read == 0)
1880384 {
1880385 //
1880386 // End of file.
1880387 //
1880388 return ((ssize_t) 0);
1880389 }
1880390 }
1880391 //
1880392 // At the moment, nothing was read.
1880393 //
1880394 size_read = 0;
1880395 //
1880396 // See if there is data to be read from
1880397 // the stream.
1880398 //
1880399 if (sfd->file->sock->tcp.can_read)
1880400 {
1880401 size_read =
1880402 min (sfd->file->sock->tcp.recv_size,
1880403 length);
1880404 memcpy (buffer,
1880405 sfd->file->sock->tcp.recv_index,
1880406 size_read);
1880407 //
1880408 sfd->file->sock->tcp.recv_size -=
1880409 size_read;
1880410 sfd->file->sock->tcp.recv_index +=
1880411 size_read;
1880412 //
1880413 if (sfd->file->sock->tcp.recv_size == 0)
1880414 {
1880415 //
1880416 // Nothing to be read at the
1880417 // moment.
1880418 //
1880419 sfd->file->sock->tcp.can_read = 0;
1880420 sfd->file->sock->tcp.can_recv = 1;
1880421 }
1880422 //
1880423 // Get the source address and
1880424 // return.
1880425 //
1880426 if (addrfrom != NULL && addrlen != NULL)
1880427 {
1880428 if (*addrlen >=
1880429 sizeof (struct sockaddr_in))
1880430 {
1880431 addrfrom_in->sin_family = AF_INET;
1880432 addrfrom_in->sin_port =
1880433 htons (sfd->file->sock->rport);
1880434 addrfrom_in->sin_addr.s_addr =
1880435 htons (sfd->file->sock->raddr);
1880436 }
1880437 *addrlen =
1880438 sizeof (struct sockaddr_in);
1880439 }
1880440 }
1880441 //
1880442 // Check if something was read.
1880443 //
1880444 if (size_read > 0)
1880445 {
1880446 //
1880447 // Return normally.
1880448 //
1880449 return ((ssize_t) size_read);
1880450 }
1880451 else
1880452 {
1880453 //
1880454 // Nothing to be read at the moment.
1880455 //
1880456 if (sfd->fl_flags & O_NONBLOCK)
1880457 {
1880458 //
1880459 // Try again.
1880460 //
1880461 errset (EAGAIN);
1880462 return ((ssize_t) - 1);
1880463 }
1880464 else
1880465 {
1880466 //
1880467 // Go to sleep and return a
1880468 // temporary error.
1880469 //
1880470 proc_table[pid].status =
1880471 PROC_SLEEPING;
1880472 proc_table[pid].ret = 0;
1880473 proc_table[pid].wakeup_events
1880474 = WAKEUP_EVENT_SOCK_READ;
1880475 proc_table[pid].wakeup_sock =
1880476 sfd->file->sock;
1880477 if (DEBUG)
1880478 {
1880479 k_printf
1880480 ("[%s:%i] PID %i goes to "
1880481 "sleep waiting to "
1880482 "receive for a socket.\n",
1880483 __FILE__, __LINE__, pid);
1880484 }
1880485 //
1880486 // Nothing was received.
1880487 //
1880488 errset (EAGAIN);
1880489 return ((ssize_t) - 1);
1880490 }
1880491 }
1880492 }
1880493 else
1880494 {
1880495 //
1880496 // Unsupported protocol.
1880497 //
1880498 errset (EPROTONOSUPPORT);
1880499 return ((ssize_t) - 1);
1880500 }
1880501 }
1880502 else
1880503 {
1880504 //
1880505 // Unsupported type.
1880506 //
1880507 errset (EPROTONOSUPPORT);
1880508 return ((ssize_t) - 1);
1880509 }
1880510 }
1880511 else
1880512 {
1880513 //
1880514 // Unsupported family.
1880515 //
1880516 errset (EAFNOSUPPORT);
1880517 return ((ssize_t) - 1);
1880518 }
1880519 //
1880520 // If we are here, there are no more packets to read
1880521 // at the moment.
1880522 //
1880523 if (sfd->fl_flags & O_NONBLOCK)
1880524 {
1880525 //
1880526 // Try again.
1880527 //
1880528 errset (EAGAIN);
1880529 return (-1);
1880530 }
1880531 else
1880532 {
1880533 //
1880534 // The process should go to sleep.
1880535 //
1880536 proc_table[pid].status = PROC_SLEEPING;
1880537 proc_table[pid].ret = 0;
1880538 proc_table[pid].wakeup_events =
1880539 WAKEUP_EVENT_SOCK_READ;
1880540 proc_table[pid].wakeup_sock = sfd->file->sock;
1880541 if (DEBUG)
1880542 {
1880543 k_printf ("[%s:%i] PID %i goes to sleep "
1880544 "waiting to receive "
1880545 "for a socket.\n",
1880546 __FILE__, __LINE__, pid);
1880547 }
1880548 //
1880549 // Try again.
1880550 //
1880551 errset (EAGAIN);
1880552 return ((ssize_t) - 1);
1880553 }
1880554 }
|
|
94.8.31
kernel/lib_s/s_routeadd.c
Si veda la sezione 87.42.
1890001 #include <arpa/inet.h>
1890002 #include <sys/os32.h>
1890003 #include <kernel/net/route.h>
1890004 #include <kernel/lib_k.h>
1890005 #include <errno.h>
1890006 #include <netinet/in.h>
1890007 #include <kernel/proc.h>
1890008 //----------------------------------------------------------
1890009 // This syscall is present only inside os32.
1890010 //----------------------------------------------------------
1890011 int
1890012 s_routeadd (pid_t pid, in_addr_t dest, int m,
1890013 in_addr_t router, int device)
1890014 {
1890015 int r;
1890016 h_addr_t netmask;
1890017 h_addr_t network;
1890018 //
1890019 // Must be a privileged process.
1890020 //
1890021 if (proc_table[pid].euid != 0)
1890022 {
1890023 errset (EPERM);
1890024 return (-1);
1890025 }
1890026 //
1890027 //
1890028 //
1890029 if (m > 32 || m < 0)
1890030 {
1890031 errset (EINVAL);
1890032 return (-1);
1890033 }
1890034 //
1890035 // Calculate the netmask.
1890036 //
1890037 netmask = ip_mask (m);
1890038 //
1890039 // Fix the destination address, with the mask.
1890040 //
1890041 network = ntohl (dest) & netmask;
1890042 //
1890043 // Check if there is already. If there is: update
1890044 // it.
1890045 //
1890046 for (r = 0; r < ROUTE_MAX_ROUTES; r++)
1890047 {
1890048 if (network == route_table[r].network
1890049 && m == route_table[r].m)
1890050 {
1890051 //
1890052 // Update.
1890053 //
1890054 route_table[r].router = ntohl (router);
1890055 route_table[r].netmask = netmask;
1890056 route_table[r].interface = device;
1890057 return (0);
1890058 }
1890059 }
1890060 //
1890061 // The item is new. Find an empty place.
1890062 //
1890063 for (r = 0; r < ROUTE_MAX_ROUTES; r++)
1890064 {
1890065 if (route_table[r].network == 0xFFFFFFFF)
1890066 {
1890067 //
1890068 // Empty.
1890069 //
1890070 route_table[r].network = network;
1890071 route_table[r].netmask = netmask;
1890072 route_table[r].m = m;
1890073 route_table[r].router = ntohl (router);
1890074 route_table[r].interface = device;
1890075 //
1890076 route_sort ();
1890077 //
1890078 return (0);
1890079 }
1890080 }
1890081 //
1890082 // No free space found.
1890083 //
1890084 errset (ENOMEM);
1890085 return (-1);
1890086 }
|
|
94.8.32
kernel/lib_s/s_routedel.c
Si veda la sezione 87.43.
1900001 #include <arpa/inet.h>
1900002 #include <sys/os32.h>
1900003 #include <kernel/net/route.h>
1900004 #include <kernel/lib_k.h>
1900005 #include <errno.h>
1900006 #include <netinet/in.h>
1900007 #include <kernel/proc.h>
1900008 //----------------------------------------------------------
1900009 // This syscall is present only inside os32.
1900010 //----------------------------------------------------------
1900011 int
1900012 s_routedel (pid_t pid, in_addr_t dest, int m)
1900013 {
1900014 int r;
1900015 h_addr_t network;
1900016 //
1900017 // Must be a privileged process.
1900018 //
1900019 if (proc_table[pid].euid != 0)
1900020 {
1900021 errset (EPERM);
1900022 return (-1);
1900023 }
1900024 //
1900025 //
1900026 //
1900027 if (m > 32 || m < 0)
1900028 {
1900029 errset (EINVAL);
1900030 return (-1);
1900031 }
1900032 //
1900033 // Calculate the destination network with the mask.
1900034 //
1900035 network = ntohl (dest) & ip_mask (m);
1900036 //
1900037 // Check if there is already. If there is: remove
1900038 // it.
1900039 //
1900040 for (r = 0; r < ROUTE_MAX_ROUTES; r++)
1900041 {
1900042 if (network == route_table[r].network
1900043 && m == route_table[r].m)
1900044 {
1900045 //
1900046 // Remove.
1900047 //
1900048 memset (&route_table[m], 0xFF,
1900049 sizeof (route_table[m]));
1900050 return (0);
1900051 }
1900052 }
1900053 //
1900054 // Not found.
1900055 //
1900056 errset (EINVAL);
1900057 return (-1);
1900058 }
|
|
94.8.33
kernel/lib_s/s_sbrk.c
Si veda la sezione 87.5.
1910001 #include <errno.h>
1910002 #include <kernel/proc.h>
1910003 #include <kernel/lib_k.h>
1910004 #include <kernel/lib_s.h>
1910005 //----------------------------------------------------------
1910006 void *
1910007 s_sbrk (pid_t pid, intptr_t increment)
1910008 {
1910009 size_t previous_size;
1910010 size_t new_size;
1910011 int status;
1910012 //
1910013 // Get current data segment full size.
1910014 //
1910015 if (proc_table[pid].domain_data == 0)
1910016 {
1910017 previous_size = (proc_table[pid].domain_text
1910018 + proc_table[pid].extra_data);
1910019 }
1910020 else
1910021 {
1910022 previous_size = (proc_table[pid].domain_data
1910023 + proc_table[pid].extra_data);
1910024 }
1910025 //
1910026 // Check increment.
1910027 //
1910028 if ((increment + proc_table[pid].extra_data) < 0)
1910029 {
1910030 //
1910031 // Cannot reduce too much. Just correct it.
1910032 //
1910033 increment = -proc_table[pid].extra_data;
1910034 }
1910035 //
1910036 // Calculate the new size.
1910037 //
1910038 new_size = previous_size + increment;
1910039 //
1910040 // Call `s_brk()' to do the work. The new size value
1910041 // is the
1910042 // same of the new requested pointer address.
1910043 //
1910044 status = s_brk (pid, (void *) new_size);
1910045 //
1910046 if (status < 0)
1910047 {
1910048 errset (errno);
1910049 return ((void *) -1);
1910050 }
1910051 //
1910052 // Ok: return previous final address.
1910053 //
1910054 return ((void *) previous_size);
1910055 }
|
|
94.8.34
kernel/lib_s/s_send.c
Si veda la sezione 87.45.
1920001 #include <kernel/proc.h>
1920002 #include <kernel/net.h>
1920003 #include <kernel/net/route.h>
1920004 #include <kernel/net/udp.h>
1920005 #include <errno.h>
1920006 #include <arpa/inet.h>
1920007 #include <fcntl.h>
1920008 #include <sys/os32.h>
1920009 //----------------------------------------------------------
1920010 #define DEBUG 0
1920011 //----------------------------------------------------------
1920012 ssize_t
1920013 s_send (pid_t pid, int sfdn, const void *buffer,
1920014 size_t size, int flags)
1920015 {
1920016 fd_t *sfd;
1920017 int status;
1920018 //
1920019 // Get file descriptor and verify that it is a
1920020 // socket.
1920021 //
1920022 sfd = fd_reference (pid, &sfdn);
1920023 if (sfd == NULL || sfd->file == NULL)
1920024 {
1920025 errset (EBADF); // Bad file descriptor.
1920026 return ((ssize_t) - 1);
1920027 }
1920028 if (sfd->file->sock == NULL)
1920029 {
1920030 errset (ENOTSOCK); // Not a socket.
1920031 return ((ssize_t) - 1);
1920032 }
1920033 if (sfd->file->sock->unreach_port)
1920034 {
1920035 errset (ECONNREFUSED); // Connection refused.
1920036 return ((ssize_t) - 1);
1920037 }
1920038 if (sfd->file->sock->unreach_prot)
1920039 {
1920040 errset (ENOPROTOOPT); // Protocol not
1920041 // available.
1920042 return ((ssize_t) - 1);
1920043 }
1920044 if (sfd->file->sock->unreach_host)
1920045 {
1920046 errset (EHOSTUNREACH); // Host unreachable.
1920047 return ((ssize_t) - 1);
1920048 }
1920049 if (sfd->file->sock->unreach_net)
1920050 {
1920051 errset (ENETUNREACH); // Net unreachable.
1920052 return ((ssize_t) - 1);
1920053 }
1920054 //
1920055 // Verify to have a valid buffer pointer.
1920056 //
1920057 if (buffer == NULL)
1920058 {
1920059 errset (EINVAL);
1920060 return ((ssize_t) - 1);
1920061 }
1920062 //
1920063 //
1920064 //
1920065 if (sfd->file->sock->family == AF_INET)
1920066 {
1920067 //
1920068 // INET
1920069 //
1920070 // AF_INET requires at least the remote address.
1920071 //
1920072 if (sfd->file->sock->raddr == 0)
1920073 {
1920074 errset (EDESTADDRREQ);
1920075 return ((ssize_t) - 1);
1920076 }
1920077 //
1920078 if (sfd->file->sock->type == SOCK_RAW)
1920079 {
1920080 //
1920081 // RAW
1920082 //
1920083 if (sfd->file->sock->protocol == IPPROTO_ICMP)
1920084 {
1920085 //
1920086 // ICMP
1920087 //
1920088 status = ip_tx (sfd->file->sock->laddr,
1920089 sfd->file->sock->raddr,
1920090 sfd->file->sock->protocol,
1920091 buffer, size);
1920092 if (status)
1920093 {
1920094 errset (errno);
1920095 return ((ssize_t) - 1);
1920096 }
1920097 else
1920098 {
1920099 return ((ssize_t) size);
1920100 }
1920101 }
1920102 else
1920103 {
1920104 //
1920105 // Unsupported protocol.
1920106 //
1920107 errset (EPROTONOSUPPORT);
1920108 return ((ssize_t) - 1);
1920109 }
1920110 }
1920111 else if (sfd->file->sock->type == SOCK_DGRAM)
1920112 {
1920113 //
1920114 // DGRAM
1920115 //
1920116 if (sfd->file->sock->protocol == IPPROTO_UDP)
1920117 {
1920118 //
1920119 // UDP
1920120 //
1920121 status = udp_tx (sfd->file->sock->lport,
1920122 sfd->file->sock->rport,
1920123 sfd->file->sock->laddr,
1920124 sfd->file->sock->raddr,
1920125 buffer, size);
1920126 if (status)
1920127 {
1920128 errset (errno);
1920129 return ((ssize_t) - 1);
1920130 }
1920131 else
1920132 {
1920133 return ((ssize_t) size);
1920134 }
1920135 }
1920136 else
1920137 {
1920138 //
1920139 // Unsupported protocol.
1920140 //
1920141 errset (EPROTONOSUPPORT);
1920142 return ((ssize_t) - 1);
1920143 }
1920144 }
1920145 else if (sfd->file->sock->type == SOCK_STREAM)
1920146 {
1920147 //
1920148 // STREAM
1920149 //
1920150 if (sfd->file->sock->protocol == IPPROTO_TCP)
1920151 {
1920152 //
1920153 // TCP
1920154 //
1920155 // See if the send side of the stream
1920156 // was closed.
1920157 //
1920158 if (sfd->file->sock->tcp.send_closed
1920159 || sfd->file->sock->tcp.conn == TCP_CLOSE)
1920160 {
1920161 //
1920162 // End of file.
1920163 //
1920164 if (DEBUG)
1920165 {
1920166 k_printf ("end of socket write\n");
1920167 }
1920168 s_kill ((pid_t) 0, pid, SIGPIPE);
1920169 errset (EPIPE);
1920170 return ((ssize_t) - 1);
1920171 }
1920172 //
1920173 // Put data to the send buffer, if it is
1920174 // possible.
1920175 //
1920176 if (sfd->file->sock->tcp.can_write)
1920177 {
1920178 size =
1920179 min (size,
1920180 (TCP_MSS -
1920181 sizeof (struct tcphdr)));
1920182 memcpy (sfd->file->sock->tcp.send_data,
1920183 buffer, size);
1920184 sfd->file->sock->tcp.send_size = size;
1920185 sfd->file->sock->tcp.can_write = 0;
1920186 sfd->file->sock->tcp.can_send = 1;
1920187 //
1920188 sfd->file->sock->tcp.lsq[++sfd->
1920189 file->sock->tcp.
1920190 lsqi] =
1920191 sfd->file->sock->tcp.lsq_ack;
1920192 sfd->file->sock->tcp.send_flags =
1920193 TCP_FLAG_PSH | TCP_FLAG_ACK;
1920194 tcp_tx_sock (sfd->file->sock);
1920195 //
1920196 return ((ssize_t) size);
1920197 }
1920198 else
1920199 {
1920200 //
1920201 // At the moment, nothing can be
1920202 // written.
1920203 //
1920204 if (sfd->fl_flags & O_NONBLOCK)
1920205 {
1920206 //
1920207 // Cannot block.
1920208 //
1920209 errset (EAGAIN);
1920210 return ((ssize_t) - 1);
1920211 }
1920212 else
1920213 {
1920214 //
1920215 // Go to sleep and return zero.
1920216 //
1920217 proc_table[pid].status =
1920218 PROC_SLEEPING;
1920219 proc_table[pid].ret = 0;
1920220 proc_table[pid].wakeup_events
1920221 = WAKEUP_EVENT_SOCK_WRITE;
1920222 proc_table[pid].wakeup_sock =
1920223 sfd->file->sock;
1920224 if (DEBUG)
1920225 {
1920226 k_printf
1920227 ("[%s] PID %i goes to "
1920228 "sleep waiting to write "
1920229 "to a socket.\n",
1920230 __FILE__, pid);
1920231 }
1920232 //
1920233 // Retry.
1920234 //
1920235 errset (EAGAIN);
1920236 return ((ssize_t) - 1);
1920237 }
1920238 }
1920239 }
1920240 else
1920241 {
1920242 //
1920243 // Unsupported protocol.
1920244 //
1920245 errset (EPROTONOSUPPORT);
1920246 return ((ssize_t) - 1);
1920247 }
1920248 }
1920249 else
1920250 {
1920251 //
1920252 // Unsupported type.
1920253 //
1920254 errset (EPROTONOSUPPORT);
1920255 return ((ssize_t) - 1);
1920256 }
1920257 }
1920258 else
1920259 {
1920260 //
1920261 // Unsupported family.
1920262 //
1920263 errset (EAFNOSUPPORT);
1920264 return ((ssize_t) - 1);
1920265 }
1920266 }
|
|
94.8.35
kernel/lib_s/s_setegid.c
Si veda la sezione 87.48.
1930001 #include <kernel/proc.h>
1930002 #include <kernel/lib_s.h>
1930003 #include <errno.h>
1930004 //----------------------------------------------------------
1930005 int
1930006 s_setegid (pid_t pid, gid_t egid)
1930007 {
1930008 if ((proc_table[pid].euid == 0)
1930009 || (proc_table[pid].egid == 0))
1930010 {
1930011 proc_table[pid].egid = egid;
1930012 return (0);
1930013 }
1930014 else if (egid == proc_table[pid].egid)
1930015 {
1930016 return (0);
1930017 }
1930018 else if (egid == proc_table[pid].gid
1930019 || egid == proc_table[pid].sgid)
1930020 {
1930021 proc_table[pid].egid = egid;
1930022 return (0);
1930023 }
1930024 else
1930025 {
1930026 errset (EPERM);
1930027 return (-1);
1930028 }
1930029 }
|
|
94.8.36
kernel/lib_s/s_seteuid.c
Si veda la sezione 87.51.
1940001 #include <kernel/proc.h>
1940002 #include <kernel/lib_s.h>
1940003 #include <errno.h>
1940004 //----------------------------------------------------------
1940005 int
1940006 s_seteuid (pid_t pid, uid_t euid)
1940007 {
1940008 if (proc_table[pid].euid == 0)
1940009 {
1940010 proc_table[pid].euid = euid;
1940011 return (0);
1940012 }
1940013 else if (euid == proc_table[pid].euid)
1940014 {
1940015 return (0);
1940016 }
1940017 else if (euid == proc_table[pid].uid
1940018 || euid == proc_table[pid].suid)
1940019 {
1940020 proc_table[pid].euid = euid;
1940021 return (0);
1940022 }
1940023 else
1940024 {
1940025 errset (EPERM);
1940026 return (-1);
1940027 }
1940028 }
|
|
94.8.37
kernel/lib_s/s_setgid.c
Si veda la sezione 87.48.
1950001 #include <kernel/proc.h>
1950002 #include <kernel/lib_s.h>
1950003 #include <errno.h>
1950004 //----------------------------------------------------------
1950005 int
1950006 s_setgid (pid_t pid, gid_t gid)
1950007 {
1950008 if ((proc_table[pid].euid == 0)
1950009 || (proc_table[pid].egid == 0))
1950010 {
1950011 proc_table[pid].gid = gid;
1950012 proc_table[pid].egid = gid;
1950013 proc_table[pid].sgid = gid;
1950014 return (0);
1950015 }
1950016 else if (gid == proc_table[pid].egid)
1950017 {
1950018 return (0);
1950019 }
1950020 else if (gid == proc_table[pid].gid
1950021 || gid == proc_table[pid].sgid)
1950022 {
1950023 proc_table[pid].egid = gid;
1950024 return (0);
1950025 }
1950026 else
1950027 {
1950028 errset (EPERM);
1950029 return (-1);
1950030 }
1950031 }
|
|
94.8.38
kernel/lib_s/s_setjmp.c
Si veda la sezione 87.49.
1960001 #include <kernel/lib_s.h>
1960002 #include <kernel/proc.h>
1960003 #include <errno.h>
1960004 #include <setjmp.h>
1960005 //----------------------------------------------------------
1960006 extern uint32_t proc_stack_pointer;
1960007 //----------------------------------------------------------
1960008 int
1960009 s_setjmp (pid_t pid, jmp_buf env)
1960010 {
1960011 jmp_stack_t *sp;
1960012 jmp_env_t *jmpenv;
1960013 //
1960014 // Find where is the process stack in memory, from
1960015 // the kernel point
1960016 // of view. Please notice that the current stack at
1960017 // `proc_stack_pointer' will be saved from the
1960018 // scheduler inside
1960019 // the process table, and current stack saved inside
1960020 // the process
1960021 // table is not up to date.
1960022 //
1960023 sp = ptr (pid, (void *) proc_stack_pointer);
1960024 //
1960025 // Translate the pointer `env', to the kernel point
1960026 // of view.
1960027 //
1960028 jmpenv = ptr (pid, env);
1960029 //
1960030 // Save the process stack.
1960031 //
1960032 jmpenv->eax0 = sp->eax0;
1960033 jmpenv->ecx0 = sp->ecx0;
1960034 jmpenv->edx0 = sp->edx0;
1960035 jmpenv->ebx0 = sp->ebx0;
1960036 jmpenv->ebp0 = sp->ebp0;
1960037 jmpenv->esi0 = sp->esi0;
1960038 jmpenv->edi0 = sp->edi0;
1960039 jmpenv->ds0 = sp->ds0;
1960040 jmpenv->es0 = sp->es0;
1960041 jmpenv->fs0 = sp->fs0;
1960042 jmpenv->gs0 = sp->gs0;
1960043 jmpenv->eflags0 = sp->eflags0;
1960044 jmpenv->cs0 = sp->cs0;
1960045 jmpenv->eip0 = sp->eip0;
1960046 //
1960047 jmpenv->eip1 = sp->eip1;
1960048 jmpenv->syscallnr = sp->syscallnr;
1960049 jmpenv->msg_pointer = sp->msg_pointer;
1960050 jmpenv->msg_size = sp->msg_size;
1960051 jmpenv->env = sp->env;
1960052 jmpenv->ret = sp->ret;
1960053 jmpenv->ebp1 = sp->ebp1;
1960054 jmpenv->eip2 = sp->eip2;
1960055 //
1960056 // Save also the stack pointer!
1960057 //
1960058 jmpenv->esp0 = proc_stack_pointer;
1960059 //
1960060 return 0;
1960061 }
|
|
94.8.39
kernel/lib_s/s_setuid.c
Si veda la sezione 87.51.
1970001 #include <kernel/proc.h>
1970002 #include <kernel/lib_s.h>
1970003 #include <errno.h>
1970004 //----------------------------------------------------------
1970005 int
1970006 s_setuid (pid_t pid, uid_t uid)
1970007 {
1970008 if (proc_table[pid].euid == 0)
1970009 {
1970010 proc_table[pid].uid = uid;
1970011 proc_table[pid].euid = uid;
1970012 proc_table[pid].suid = uid;
1970013 return (0);
1970014 }
1970015 else if (uid == proc_table[pid].euid)
1970016 {
1970017 return (0);
1970018 }
1970019 else if (uid == proc_table[pid].uid
1970020 || uid == proc_table[pid].suid)
1970021 {
1970022 proc_table[pid].euid = uid;
1970023 return (0);
1970024 }
1970025 else
1970026 {
1970027 errset (EPERM);
1970028 return (-1);
1970029 }
1970030 }
|
|
94.8.40
kernel/lib_s/s_signal.c
Si veda la sezione 87.52.
1980001 #include <kernel/lib_s.h>
1980002 #include <kernel/proc.h>
1980003 #include <errno.h>
1980004 //----------------------------------------------------------
1980005 sighandler_t
1980006 s_signal (pid_t pid, int sig, sighandler_t handler,
1980007 uintptr_t wrapper)
1980008 {
1980009 unsigned long int flag = 1L << (sig - 1);
1980010 sighandler_t previous;
1980011 //
1980012 if (sig <= 0)
1980013 {
1980014 errset (EINVAL);
1980015 return (SIG_ERR);
1980016 }
1980017 //
1980018 if (proc_table[pid].sig_ignore & flag)
1980019 {
1980020 previous = SIG_IGN;
1980021 }
1980022 else if (proc_table[pid].sig_handler[sig] !=
1980023 (uintptr_t) NULL)
1980024 {
1980025 previous =
1980026 (sighandler_t) proc_table[pid].sig_handler[sig];
1980027 }
1980028 else
1980029 {
1980030 previous = SIG_DFL;
1980031 }
1980032 //
1980033 if (handler == SIG_DFL)
1980034 {
1980035 //
1980036 // Enable signal.
1980037 //
1980038 proc_table[pid].sig_ignore &= ~flag;
1980039 //
1980040 return (previous);
1980041 }
1980042 else if (handler == SIG_IGN)
1980043 {
1980044 //
1980045 // Disable signal.
1980046 //
1980047 proc_table[pid].sig_ignore |= flag;
1980048 //
1980049 return (previous);
1980050 }
1980051 else
1980052 {
1980053 //
1980054 // Enable signal, store the handler address and
1980055 // the
1980056 // handler-wrapper.
1980057 //
1980058 proc_table[pid].sig_ignore &= ~flag;
1980059 proc_table[pid].sig_handler[sig] =
1980060 (uintptr_t) handler;
1980061 proc_table[pid].sig_handler_wrapper = wrapper;
1980062 //
1980063 return (previous);
1980064 }
1980065 }
|
|
94.8.41
kernel/lib_s/s_socket.c
Si veda la sezione 87.54.
1990001 #include <kernel/proc.h>
1990002 #include <kernel/lib_s.h>
1990003 #include <kernel/lib_k.h>
1990004 #include <errno.h>
1990005 #include <fcntl.h>
1990006 #include <sys/socket.h>
1990007 #include <arpa/inet.h>
1990008 //----------------------------------------------------------
1990009 int
1990010 s_socket (pid_t pid, int family, int type, int protocol)
1990011 {
1990012 fd_t *fd;
1990013 int sfdn;
1990014 file_t *file;
1990015 sock_t *sock;
1990016 //
1990017 // Check supported family type.
1990018 //
1990019 if (family != AF_INET)
1990020 {
1990021 errset (EAFNOSUPPORT);
1990022 return (-1);
1990023 }
1990024 //
1990025 // Check supported communication type.
1990026 //
1990027 if (type == SOCK_RAW || type == SOCK_DGRAM
1990028 || type == SOCK_STREAM)
1990029 {
1990030 //
1990031 // Ok.
1990032 //
1990033 ;
1990034 }
1990035 else
1990036 {
1990037 errset (EPROTONOSUPPORT);
1990038 return (-1);
1990039 }
1990040 //
1990041 // Check supported protocol type.
1990042 //
1990043 if (protocol == IPPROTO_ICMP
1990044 || protocol == IPPROTO_UDP || protocol == IPPROTO_TCP)
1990045 {
1990046 //
1990047 // Ok.
1990048 //
1990049 ;
1990050 }
1990051 else
1990052 {
1990053 errset (EPROTONOSUPPORT);
1990054 return (-1);
1990055 }
1990056 //
1990057 // If it is a raw socket, must be a privileged
1990058 // process.
1990059 //
1990060 if (type == SOCK_RAW && proc_table[pid].euid != 0)
1990061 {
1990062 errset (EACCES);
1990063 return (-1);
1990064 }
1990065 //
1990066 // Find a free slot inside the sock_table[].
1990067 //
1990068 sock = sock_reference (-1);
1990069 if (sock == NULL)
1990070 {
1990071 errset (ENFILE);
1990072 return (-1);
1990073 }
1990074 //
1990075 // Find a free slot inside the file table.
1990076 //
1990077 file = file_reference (-1);
1990078 if (file == NULL)
1990079 {
1990080 errset (ENFILE); // Too many files open in
1990081 // system.
1990082 return (-1);
1990083 }
1990084 //
1990085 // Find a free slot inside the file descriptor
1990086 // table.
1990087 // Variable `sfdn' will be modified by the call to
1990088 // `fd_reference()'.
1990089 //
1990090 sfdn = -1;
1990091 fd = fd_reference (pid, &sfdn);
1990092 if (fd == NULL)
1990093 {
1990094 errset (EMFILE); // Too many open files.
1990095 return (-1);
1990096 }
1990097 //
1990098 // socket, system file and file descriptor ready:
1990099 // reset and put data
1990100 // inside them. Please notice that the
1990101 // tcp.listen_queue[] array is
1990102 // reset with all 0xFF, because zero is a valid file
1990103 // descriptor
1990104 // number.
1990105 //
1990106 memset (sock, 0, sizeof (sock_t));
1990107 sock->active = 1;
1990108 sock->family = family;
1990109 sock->type = type;
1990110 sock->protocol = protocol;
1990111 sock->lport = 0;
1990112 sock->laddr = 0;
1990113 sock->rport = 0;
1990114 sock->raddr = 0;
1990115 memset (sock->read.clock, 0x00,
1990116 sizeof (sock->read.clock));
1990117 memset (sock->tcp.listen_queue, 0xFF,
1990118 sizeof (sock->tcp.listen_queue));
1990119 //
1990120 file->references = 1;
1990121 file->oflags = O_RDWR;
1990122 file->inode = NULL;
1990123 file->sock = sock;
1990124 file->offset = 0;
1990125 //
1990126 fd->fl_flags = (O_RDWR | O_APPEND);
1990127 fd->fd_flags = 0;
1990128 fd->file = file;
1990129 //
1990130 // Return the file descriptor.
1990131 //
1990132 return (sfdn);
1990133 }
|
|
94.8.42
kernel/lib_s/s_stat.c
Si veda la sezione 87.55.
2000001 #include <kernel/fs.h>
2000002 #include <errno.h>
2000003 #include <kernel/proc.h>
2000004 #include <kernel/lib_s.h>
2000005 //----------------------------------------------------------
2000006 int
2000007 s_stat (pid_t pid, const char *path, struct stat *buffer)
2000008 {
2000009 proc_t *ps;
2000010 inode_t *inode;
2000011 //
2000012 // Check path.
2000013 //
2000014 if (path == NULL || strlen (path) == 0)
2000015 {
2000016 errset (EINVAL);
2000017 return (-1);
2000018 }
2000019 //
2000020 // Get process.
2000021 //
2000022 ps = proc_reference (pid);
2000023 //
2000024 // Try to load the file inode.
2000025 //
2000026 inode = path_inode (pid, path);
2000027 if (inode == NULL)
2000028 {
2000029 //
2000030 // Cannot access the file: it does not exists or
2000031 // permissions are
2000032 // not sufficient. Variable `errno' is set by
2000033 // function
2000034 // `path_inode()'.
2000035 //
2000036 errset (errno);
2000037 return (-1);
2000038 }
2000039 //
2000040 // Inode loaded: update the buffer.
2000041 //
2000042 buffer->st_dev = inode->sb->device;
2000043 buffer->st_ino = inode->ino;
2000044 buffer->st_mode = inode->mode;
2000045 buffer->st_nlink = inode->links;
2000046 buffer->st_uid = inode->uid;
2000047 buffer->st_gid = inode->gid;
2000048 if (S_ISBLK (buffer->st_mode)
2000049 || S_ISCHR (buffer->st_mode))
2000050 {
2000051 buffer->st_rdev = inode->direct[0];
2000052 }
2000053 else
2000054 {
2000055 buffer->st_rdev = 0;
2000056 }
2000057 buffer->st_size = inode->size;
2000058 buffer->st_atime = inode->time; // All times
2000059 // are the
2000060 // same for
2000061 buffer->st_mtime = inode->time; // Minix 1
2000062 // file
2000063 // system.
2000064 buffer->st_ctime = inode->time; //
2000065 buffer->st_blksize = inode->sb->blksize;
2000066 buffer->st_blocks = inode->blkcnt;
2000067 //
2000068 // If the inode is a device special file, the
2000069 // `st_rdev' value is
2000070 // taken from the first direct zone (as of Minix 1
2000071 // organization).
2000072 //
2000073 if (S_ISBLK (inode->mode) || S_ISCHR (inode->mode))
2000074 {
2000075 buffer->st_rdev = inode->direct[0];
2000076 }
2000077 else
2000078 {
2000079 buffer->st_rdev = 0;
2000080 }
2000081 //
2000082 // Release the inode and return.
2000083 //
2000084 inode_put (inode);
2000085 //
2000086 // Return.
2000087 //
2000088 return (0);
2000089 }
|
|
94.8.43
kernel/lib_s/s_stime.c
Si veda la sezione 87.59.
2010001 #include <kernel/lib_s.h>
2010002 #include <kernel/proc.h>
2010003 #include <stddef.h>
2010004 #include <errno.h>
2010005 //----------------------------------------------------------
2010006 extern clock_t _clock_time; // uint64_t
2010007 //----------------------------------------------------------
2010008 int
2010009 s_stime (pid_t pid, time_t * timer)
2010010 {
2010011 if (proc_table[pid].euid != 0)
2010012 {
2010013 errset (EPERM);
2010014 return (-1);
2010015 }
2010016 //
2010017 _clock_time = *timer * CLOCKS_PER_SEC;
2010018 return (0);
2010019 }
|
|
94.8.44
kernel/lib_s/s_tcgetattr.c
Si veda la sezione 87.58.
2020001 #include <kernel/fs.h>
2020002 #include <errno.h>
2020003 #include <kernel/proc.h>
2020004 #include <kernel/lib_s.h>
2020005 #include <termios.h>
2020006 #include <sys/types.h>
2020007 //----------------------------------------------------------
2020008 int
2020009 s_tcgetattr (pid_t pid, int fdn, struct termios *termios_p)
2020010 {
2020011 file_t *file;
2020012 inode_t *inode;
2020013 dev_t device;
2020014 int t; // `tty_table[]' subscript.
2020015 int c; // `c_cc[]' subscript.
2020016 //
2020017 file = proc_table[pid].fd[fdn].file;
2020018 //
2020019 if (file == NULL)
2020020 {
2020021 errset (EBADF);
2020022 return (-1);
2020023 }
2020024 //
2020025 inode = proc_table[pid].fd[fdn].file->inode;
2020026 //
2020027 if (inode == NULL)
2020028 {
2020029 errset (EBADF);
2020030 return (-1);
2020031 }
2020032 //
2020033 if (!S_ISCHR (inode->mode))
2020034 {
2020035 errset (ENOTTY);
2020036 return (-1);
2020037 }
2020038 //
2020039 device = inode->direct[0];
2020040 //
2020041 if (major (device) != DEV_CONSOLE_MAJOR)
2020042 {
2020043 errset (ENOTTY);
2020044 return (-1);
2020045 }
2020046 //
2020047 t = minor (device);
2020048 if (t >= TTYS_TOTAL)
2020049 {
2020050 errset (ENOTTY);
2020051 return (-1);
2020052 }
2020053 //
2020054 // Ok: copy data.
2020055 //
2020056 termios_p->c_iflag = tty_table[t].attr.c_iflag;
2020057 termios_p->c_oflag = tty_table[t].attr.c_oflag;
2020058 termios_p->c_cflag = tty_table[t].attr.c_cflag;
2020059 termios_p->c_lflag = tty_table[t].attr.c_lflag;
2020060 for (c = 0; c < NCCS; c++)
2020061 {
2020062 termios_p->c_cc[c] = tty_table[t].attr.c_cc[c];
2020063 }
2020064 //
2020065 // Ok.
2020066 //
2020067 return (0);
2020068 }
|
|
94.8.45
kernel/lib_s/s_tcsetattr.c
Si veda la sezione 87.58.
2030001 #include <kernel/fs.h>
2030002 #include <errno.h>
2030003 #include <kernel/proc.h>
2030004 #include <kernel/lib_s.h>
2030005 #include <termios.h>
2030006 #include <sys/types.h>
2030007 //----------------------------------------------------------
2030008 // The following are masks of the implemented
2030009 // attributes.
2030010 //
2030011 #define MASK_C_IFLAG (BRKINT|ICRNL|IGNBRK|IGNCR)
2030012 #define MASK_C_OFLAG 0
2030013 #define MASK_C_CFLAG 0
2030014 #define MASK_C_LFLAG \
2030015 (ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG)
2030016 //----------------------------------------------------------
2030017 int
2030018 s_tcsetattr (pid_t pid, int fdn, int action,
2030019 struct termios *termios_p)
2030020 {
2030021 file_t *file;
2030022 inode_t *inode;
2030023 dev_t device;
2030024 int t; // `tty_table[]' subscript.
2030025 int c; // `c_cc[]' subscript.
2030026 //
2030027 file = proc_table[pid].fd[fdn].file;
2030028 //
2030029 if (file == NULL)
2030030 {
2030031 errset (EBADF);
2030032 return (-1);
2030033 }
2030034 //
2030035 inode = proc_table[pid].fd[fdn].file->inode;
2030036 //
2030037 if (inode == NULL)
2030038 {
2030039 errset (EBADF);
2030040 return (-1);
2030041 }
2030042 //
2030043 if (!S_ISCHR (inode->mode))
2030044 {
2030045 errset (ENOTTY);
2030046 return (-1);
2030047 }
2030048 //
2030049 device = inode->direct[0];
2030050 //
2030051 if (major (device) != DEV_CONSOLE_MAJOR)
2030052 {
2030053 errset (ENOTTY);
2030054 return (-1);
2030055 }
2030056 //
2030057 t = minor (device);
2030058 if (t >= TTYS_TOTAL)
2030059 {
2030060 errset (ENOTTY);
2030061 return (-1);
2030062 }
2030063 //
2030064 // The parameter `actions' is silently ignored: only
2030065 // immediate update will take place.
2030066 //
2030067 // The function will not notice if at least a
2030068 // successful attribute change is done, so,
2030069 // after this point, the return value is
2030070 // always zero.
2030071 //
2030072 tty_table[t].attr.c_iflag =
2030073 (termios_p->c_iflag & MASK_C_IFLAG);
2030074 tty_table[t].attr.c_oflag =
2030075 (termios_p->c_oflag & MASK_C_OFLAG);
2030076 tty_table[t].attr.c_cflag =
2030077 (termios_p->c_cflag & MASK_C_CFLAG);
2030078 tty_table[t].attr.c_lflag =
2030079 (termios_p->c_lflag & MASK_C_LFLAG);
2030080 for (c = 0; c < NCCS; c++)
2030081 {
2030082 //
2030083 // Should be done some check here?
2030084 //
2030085 tty_table[t].attr.c_cc[c] = termios_p->c_cc[c];
2030086 }
2030087 //
2030088 // Ok.
2030089 //
2030090 return (0);
2030091 }
|
|
94.8.46
kernel/lib_s/s_time.c
Si veda la sezione 87.59.
2040001 #include <kernel/lib_k.h>
2040002 #include <kernel/lib_s.h>
2040003 #include <stddef.h>
2040004 //----------------------------------------------------------
2040005 extern clock_t _clock_time; // uint64_t
2040006 //----------------------------------------------------------
2040007 time_t
2040008 s_time (pid_t pid, time_t * timer)
2040009 {
2040010 time_t time = _clock_time / CLOCKS_PER_SEC;
2040011 if (timer != NULL)
2040012 {
2040013 *timer = time;
2040014 }
2040015 return (time);
2040016 }
|
|
94.8.47
kernel/lib_s/s_umount.c
Si veda la sezione 87.36.
2050001 #include <kernel/fs.h>
2050002 #include <errno.h>
2050003 #include <kernel/proc.h>
2050004 #include <kernel/lib_s.h>
2050005 //----------------------------------------------------------
2050006 int
2050007 s_umount (pid_t pid, const char *path_mnt)
2050008 {
2050009 proc_t *ps;
2050010 dev_t device; // Device to mount.
2050011 inode_t *inode_mount_point; // Original mount
2050012 // point.
2050013 inode_t *inode; // Inode table.
2050014 int i; // Inode table index.
2050015 //
2050016 // Get process.
2050017 //
2050018 ps = proc_reference (pid);
2050019 //
2050020 // Verify to be the super user.
2050021 //
2050022 if (ps->euid != 0)
2050023 {
2050024 errset (EPERM); // Operation not permitted.
2050025 return (-1);
2050026 }
2050027 //
2050028 // Get the directory mount point.
2050029 //
2050030 inode_mount_point = path_inode (pid, path_mnt);
2050031 if (inode_mount_point == NULL)
2050032 {
2050033 errset (ENOENT); // No such file or directory.
2050034 return (-1);
2050035 }
2050036 //
2050037 // Verify that the path is a directory.
2050038 //
2050039 if (!S_ISDIR (inode_mount_point->mode))
2050040 {
2050041 inode_put (inode_mount_point);
2050042 errset (ENOTDIR); // Not a directory.
2050043 return (-1);
2050044 }
2050045 //
2050046 // Verify that there is something attached.
2050047 //
2050048 device = inode_mount_point->sb_attached->device;
2050049 if (device == 0)
2050050 {
2050051 //
2050052 // There is nothing to unmount.
2050053 //
2050054 inode_put (inode_mount_point);
2050055 errset (E_NOT_MOUNTED); // Not mounted.
2050056 return (-1);
2050057 }
2050058 //
2050059 // Are there exactly two internal references? Let's
2050060 // explain:
2050061 // the directory that act as mount point, should
2050062 // have one reference
2050063 // because it is mounting something and another
2050064 // because it was just
2050065 // opened again, a few lines above. If there are
2050066 // more references
2050067 // it is wrong; if there are less, it is also wrong
2050068 // at this point.
2050069 //
2050070 if (inode_mount_point->references != 2)
2050071 {
2050072 inode_put (inode_mount_point);
2050073 errset (EUNKNOWN); // Unknown error.
2050074 return (-1);
2050075 }
2050076 //
2050077 // All data is available: find if there are open
2050078 // file inside
2050079 // the file system to unmount. But first load the
2050080 // inode table
2050081 // pointer.
2050082 //
2050083 inode = inode_reference ((dev_t) 0, (ino_t) 0);
2050084 if (inode == NULL)
2050085 {
2050086 //
2050087 // This error should not happen.
2050088 //
2050089 inode_put (inode_mount_point);
2050090 errset (EUNKNOWN); // Unknown error.
2050091 return (-1);
2050092 }
2050093 //
2050094 // Scan the inode table.
2050095 //
2050096 for (i = 0; i < INODE_MAX_SLOTS; i++)
2050097 {
2050098 if ((inode[i].sb ==
2050099 inode_mount_point->sb_attached)
2050100 && (inode[i].references > 0))
2050101 {
2050102 //
2050103 // At least one file is open inside the
2050104 // super block to
2050105 // release: cannot unmount.
2050106 //
2050107 inode_put (inode_mount_point);
2050108 errset (EBUSY); // Device or resource
2050109 // busy.
2050110 return (-1);
2050111 }
2050112 }
2050113 //
2050114 // Can unmount: save and remove the super block
2050115 // memory;
2050116 // clear the mount point reference and put inode.
2050117 //
2050118 inode_mount_point->sb_attached->changed = 1;
2050119 sb_save (inode_mount_point->sb_attached);
2050120 //
2050121 inode_mount_point->sb_attached->device = 0;
2050122 inode_mount_point->sb_attached->inode_mounted_on = NULL;
2050123 inode_mount_point->sb_attached->blksize = 0;
2050124 inode_mount_point->sb_attached->options = 0;
2050125 //
2050126 inode_mount_point->sb_attached = NULL;
2050127 inode_mount_point->references = 0;
2050128 inode_put (inode_mount_point);
2050129 //
2050130 inode_put (inode_mount_point);
2050131 //
2050132 return (0);
2050133 }
|
|
94.8.48
kernel/lib_s/s_unlink.c
Si veda la sezione 87.62.
2060001 #include <kernel/fs.h>
2060002 #include <errno.h>
2060003 #include <kernel/proc.h>
2060004 #include <libgen.h>
2060005 #include <kernel/lib_s.h>
2060006 #include <kernel/lib_k.h>
2060007 //----------------------------------------------------------
2060008 int
2060009 s_unlink (pid_t pid, const char *path)
2060010 {
2060011 proc_t *ps;
2060012 inode_t *inode_unlink;
2060013 inode_t *inode_directory;
2060014 char path_unlink[PATH_MAX];
2060015 char path_copy[PATH_MAX];
2060016 char *path_directory;
2060017 char *name_unlink;
2060018 dev_t device;
2060019 off_t start;
2060020 char buffer[SB_MAX_ZONE_SIZE];
2060021 directory_t *dir = (directory_t *) buffer;
2060022 int status;
2060023 ssize_t size_read;
2060024 ssize_t size_written;
2060025 int d; // Directory buffer index.
2060026 //
2060027 // Get process.
2060028 //
2060029 ps = proc_reference (pid);
2060030 //
2060031 // Get full paths.
2060032 //
2060033 path_full (path, ps->path_cwd, path_unlink);
2060034 strncpy (path_copy, path_unlink, PATH_MAX);
2060035 path_directory = dirname (path_copy);
2060036 //
2060037 // Get the inode to be unlinked.
2060038 //
2060039 inode_unlink = path_inode (pid, path_unlink);
2060040 if (inode_unlink == NULL)
2060041 {
2060042 return (-1);
2060043 }
2060044 //
2060045 // If it is a directory, verify that it is empty.
2060046 //
2060047 if (S_ISDIR (inode_unlink->mode))
2060048 {
2060049 if (!inode_dir_empty (inode_unlink))
2060050 {
2060051 inode_put (inode_unlink);
2060052 errset (ENOTEMPTY); // Directory not
2060053 // empty.
2060054 return (-1);
2060055 }
2060056 }
2060057 //
2060058 // Get the inode of the directory containing it.
2060059 //
2060060 inode_directory = path_inode (pid, path_directory);
2060061 if (inode_directory == NULL)
2060062 {
2060063 inode_put (inode_unlink);
2060064 return (-1);
2060065 }
2060066 //
2060067 // Check if something is mounted on the directory.
2060068 //
2060069 if (inode_directory->sb_attached != NULL)
2060070 {
2060071 //
2060072 // Must select the right directory.
2060073 //
2060074 device = inode_directory->sb_attached->device;
2060075 inode_put (inode_directory);
2060076 inode_directory = inode_get (device, 1);
2060077 if (inode_directory == NULL)
2060078 {
2060079 inode_put (inode_unlink);
2060080 return (-1);
2060081 }
2060082 }
2060083 //
2060084 // Check if write is allowed for the file system.
2060085 //
2060086 if (inode_directory->sb->options & MOUNT_RO)
2060087 {
2060088 errset (EROFS); // Read-only file system.
2060089 return (-1);
2060090 }
2060091 //
2060092 // Verify access permissions for the directory. The
2060093 // number "3" means
2060094 // that the user must have access permission and
2060095 // write permission:
2060096 // "-wx" == 2+1 == 3.
2060097 //
2060098 status = inode_check (inode_directory, S_IFDIR, 3,
2060099 ps->euid, ps->egid);
2060100 if (status != 0)
2060101 {
2060102 errset (EPERM); // Operation not permitted.
2060103 inode_put (inode_unlink);
2060104 inode_put (inode_directory);
2060105 return (-1);
2060106 }
2060107 //
2060108 // Get the base name to be unlinked: this will alter
2060109 // the
2060110 // original path.
2060111 //
2060112 name_unlink = basename (path_unlink);
2060113 //
2060114 // Read the directory content and try to locate the
2060115 // item to unlink.
2060116 //
2060117 for (start = 0;
2060118 start < inode_directory->size;
2060119 start += inode_directory->sb->blksize)
2060120 {
2060121 size_read =
2060122 inode_file_read (inode_directory, start,
2060123 buffer,
2060124 inode_directory->sb->blksize,
2060125 NULL);
2060126 if (size_read < sizeof (directory_t))
2060127 {
2060128 break;
2060129 }
2060130 //
2060131 // Scan the directory portion just read, for the
2060132 // item to unlink.
2060133 //
2060134 dir = (directory_t *) buffer;
2060135 //
2060136 for (d = 0; d < size_read;
2060137 d += (sizeof (directory_t)), dir++)
2060138 {
2060139 if ((dir->ino != 0)
2060140 &&
2060141 (strncmp
2060142 (dir->name, name_unlink, NAME_MAX) == 0))
2060143 {
2060144 //
2060145 // Found the corresponding item: unlink
2060146 // the inode.
2060147 //
2060148 dir->ino = 0;
2060149 //
2060150 // Update the directory inside the file
2060151 // system.
2060152 //
2060153 size_written =
2060154 inode_file_write (inode_directory,
2060155 start, buffer, size_read);
2060156 if (size_written != size_read)
2060157 {
2060158 //
2060159 // Write problem: just tell.
2060160 //
2060161 k_printf
2060162 ("kernel alert: directory "
2060163 "write error!\n");
2060164 }
2060165 //
2060166 // Update directory inode and put inode.
2060167 // If the unlinked
2060168 // inode was a directory, the parent
2060169 // directory inode
2060170 // must reduce the file system link
2060171 // count.
2060172 //
2060173 if (S_ISDIR (inode_unlink->mode))
2060174 {
2060175 inode_directory->links--;
2060176 }
2060177 inode_directory->time = s_time (pid, NULL);
2060178 inode_directory->changed = 1;
2060179 inode_put (inode_directory);
2060180 //
2060181 // Reduce link inside unlinked inode and
2060182 // put inode.
2060183 //
2060184 inode_unlink->links--;
2060185 inode_unlink->changed = 1;
2060186 inode_unlink->time = s_time (pid, NULL);
2060187 inode_put (inode_unlink);
2060188 //
2060189 // Just return, as the work is done.
2060190 //
2060191 return (0);
2060192 }
2060193 }
2060194 }
2060195 //
2060196 // At this point, it was not possible to unlink the
2060197 // file.
2060198 //
2060199 inode_put (inode_unlink);
2060200 inode_put (inode_directory);
2060201 errset (EUNKNOWN); // Unknown error.
2060202 return (-1);
2060203 }
|
|
94.8.49
kernel/lib_s/s_wait.c
Si veda la sezione 87.63.
2070001 #include <kernel/proc.h>
2070002 #include <kernel/lib_s.h>
2070003 #include <errno.h>
2070004 //----------------------------------------------------------
2070005 pid_t
2070006 s_wait (pid_t pid, int *status)
2070007 {
2070008 pid_t parent = pid;
2070009 pid_t child;
2070010 int child_available = 0;
2070011 //
2070012 // Find a dead child process.
2070013 //
2070014 for (child = 1; child < PROCESS_MAX; child++)
2070015 {
2070016 if (proc_table[child].ppid == parent)
2070017 {
2070018 child_available = 1; // Child found!
2070019 if (proc_table[child].status == PROC_ZOMBIE)
2070020 {
2070021 break; // It is dead!
2070022 }
2070023 }
2070024 }
2070025 //
2070026 // If the index `child' is a valid process number,
2070027 // a dead child was found.
2070028 //
2070029 if (child < PROCESS_MAX)
2070030 {
2070031 *status = proc_table[child].ret;
2070032 proc_available (child);
2070033 return (child);
2070034 }
2070035 else
2070036 {
2070037 if (child_available)
2070038 {
2070039 //
2070040 // There are child, but all alive.
2070041 //
2070042 // Go to sleep.
2070043 //
2070044 proc_table[parent].status = PROC_SLEEPING;
2070045 proc_table[parent].wakeup_events =
2070046 WAKEUP_EVENT_SIGNAL;
2070047 proc_table[parent].wakeup_signal = SIGCHLD;
2070048 return ((pid_t) 0);
2070049 }
2070050 else
2070051 {
2070052 //
2070053 // There are no child at all.
2070054 //
2070055 errset (ECHILD);
2070056 return ((pid_t) - 1);
2070057 }
2070058 }
2070059 }
|
|
94.8.50
kernel/lib_s/s_write.c
Si veda la sezione 87.64.
2080001 #include <kernel/proc.h>
2080002 #include <kernel/lib_s.h>
2080003 #include <errno.h>
2080004 #include <fcntl.h>
2080005 //----------------------------------------------------------
2080006 #define DEBUG 0
2080007 //----------------------------------------------------------
2080008 ssize_t
2080009 s_write (pid_t pid, int fdn, const void *buffer,
2080010 size_t count)
2080011 {
2080012 proc_t *ps;
2080013 fd_t *fd;
2080014 ssize_t size_written;
2080015 int status;
2080016 //
2080017 // Get process.
2080018 //
2080019 ps = proc_reference (pid);
2080020 //
2080021 // Get file descriptor.
2080022 //
2080023 fd = fd_reference (pid, &fdn);
2080024 if (fd == NULL || fd->file == NULL
2080025 || (fd->file->inode == NULL
2080026 && fd->file->sock == NULL))
2080027 {
2080028 //
2080029 // The file descriptor pointer is not valid.
2080030 //
2080031 errset (EBADF); // Bad file descriptor.
2080032 return ((ssize_t) - 1);
2080033 }
2080034 //
2080035 // Check if it is opened for write.
2080036 //
2080037 if (!(fd->file->oflags & O_WRONLY))
2080038 {
2080039 //
2080040 // The file is not opened for write.
2080041 //
2080042 errset (EINVAL); // Invalid argument.
2080043 return ((ssize_t) - 1);
2080044 }
2080045 //
2080046 // Check if it is a directory inode: a directory can
2080047 // be
2080048 // read as a file descriptor, but cannot be written.
2080049 //
2080050 if (fd->file->inode != NULL
2080051 && (fd->file->inode->mode & S_IFDIR))
2080052 {
2080053 errset (EISDIR); // Is a directory.
2080054 return ((ssize_t) - 1);
2080055 }
2080056 //
2080057 // It should be a valid type of file or socket to be
2080058 // written.
2080059 // Check if it is a file opened in append mode: if
2080060 // so, must move
2080061 // the write offset to the end.
2080062 //
2080063 if (fd->file->inode != NULL && (fd->fl_flags & O_APPEND))
2080064 {
2080065 fd->file->offset = fd->file->inode->size;
2080066 }
2080067 //
2080068 // Check the kind of socket/file to be written and
2080069 // write it.
2080070 //
2080071 if (fd->file->sock != NULL)
2080072 {
2080073 //
2080074 // Send it.
2080075 //
2080076 size_written = s_send (pid, fdn, buffer, count, 0);
2080077 }
2080078 else if (fd->file->inode->mode & S_IFBLK ||
2080079 fd->file->inode->mode & S_IFCHR)
2080080 {
2080081 //
2080082 // A device is to be written.
2080083 //
2080084 size_written =
2080085 dev_io (pid,
2080086 (dev_t) fd->file->inode->direct[0],
2080087 DEV_WRITE, (off_t) fd->file->offset,
2080088 (void *) buffer, count, NULL);
2080089 }
2080090 else if (fd->file->inode->mode & S_IFREG)
2080091 {
2080092 //
2080093 // A regular file is to be written.
2080094 //
2080095 size_written = inode_file_write (fd->file->inode,
2080096 fd->file->offset,
2080097 buffer, count);
2080098 }
2080099 else if (fd->file->inode->mode & S_IFIFO)
2080100 {
2080101 //
2080102 // A pipe is to be written.
2080103 //
2080104 size_written =
2080105 inode_pipe_write (fd->file->inode, buffer, count);
2080106 if (size_written == 0)
2080107 {
2080108 if (fd->file->inode->pipe_ref_read == 0)
2080109 {
2080110 //
2080111 // No read will be done anymore. Tell to
2080112 // the process.
2080113 //
2080114 status = s_kill ((pid_t) 0, pid, SIGPIPE);
2080115 if (status < 0)
2080116 {
2080117 errset (EPIPE);
2080118 return ((ssize_t) - 1);
2080119 }
2080120 else
2080121 {
2080122 //
2080123 // Wake up processes waiting to
2080124 // read.
2080125 //
2080126 proc_wakeup_pipe_read (fd->file->inode);
2080127 }
2080128 }
2080129 else
2080130 {
2080131 //
2080132 // At the moment, nothing can be
2080133 // written.
2080134 //
2080135 if (fd->fl_flags & O_NONBLOCK)
2080136 {
2080137 //
2080138 // Cannot block.
2080139 //
2080140 errset (EAGAIN);
2080141 return ((ssize_t) - 1);
2080142 }
2080143 else
2080144 {
2080145 //
2080146 // Go to sleep.
2080147 //
2080148 proc_table[pid].status = PROC_SLEEPING;
2080149 proc_table[pid].ret = 0;
2080150 proc_table[pid].wakeup_inode =
2080151 fd->file->inode;
2080152 proc_table[pid].wakeup_events =
2080153 WAKEUP_EVENT_PIPE_WRITE;
2080154 if (DEBUG)
2080155 {
2080156 k_printf
2080157 ("[%s] PID %i goes to sleep "
2080158 "waiting to write inside "
2080159 "a pipe.\n", __FILE__, pid);
2080160 }
2080161 }
2080162 }
2080163 }
2080164 else
2080165 {
2080166 //
2080167 // Wake up processes waiting to read.
2080168 //
2080169 proc_wakeup_pipe_read (fd->file->inode);
2080170 }
2080171 }
2080172 else
2080173 {
2080174 //
2080175 // Unsupported file type.
2080176 //
2080177 errset (E_FILE_TYPE_UNSUPPORTED); // File type
2080178 // unsupported.
2080179 return ((ssize_t) - 1);
2080180 }
2080181 //
2080182 // Update the file descriptor internal offset, but
2080183 // only if it
2080184 // is a file.
2080185 //
2080186 if (fd->file->sock == NULL && size_written > 0)
2080187 {
2080188 fd->file->offset += size_written;
2080189 }
2080190 //
2080191 // Just return the size written, even if it is an
2080192 // error.
2080193 //
2080194 return (size_written);
2080195 }
|
|
94.9
os32: «kernel/main.h»
Si veda la sezione 93.13.
2090001 #ifndef _KERNEL_MAIN_H
2090002 #define _KERNEL_MAIN_H 1
2090003 //----------------------------------------------------------
2090004 #include <kernel/multiboot.h>
2090005 #include <stdint.h>
2090006 #include <sys/types.h>
2090007 //----------------------------------------------------------
2090008 void kmain (uint32_t magic, multiboot_t * mboot_data);
2090009 void menu (void);
2090010 pid_t run (char *path, char *argv[], char *envp[]);
2090011 //----------------------------------------------------------
2090012 #endif
|
|
94.9.1
kernel/main/build.h
Si veda la sezione 93.13.
2100001 #define BUILD_DATE "201108311936"
|
|
94.9.2
kernel/main/crt0.s
Si veda la sezione 84.2.2.
2110001 .extern kmain
2110002 .extern _k_stack_top
2110003 .extern _k_stack_bottom
2110004 .global kstartup
2110005 #######################################################
2110006 #
2110007 # The kernel must be compiled as ELF, so that the
2110008 # bootloader (GRUB or SYSLINUX) can recognize it.
2110009 #
2110010 #------------------------------------------------------
2110011 .section .text
2110012 #------------------------------------------------------
2110013 #
2110014 # At the beginning there is the code, but inside the
2110015 # code there is also the multiboot header.
2110016 # This is why we start with a jump.
2110017 #
2110018 kstartup:
2110019 jmp start
2110020 #
2110021 # Here is the multiboot header, that must be placed
2110022 # near the beginning of the image-file, but aligned at
2110023 # a multiple of four bytes.
2110024 #
2110025 .align 4
2110026 multiboot_header:
2110027 .int 0x1BADB002 # magic
2110028 .int 0x00000007 # flags
2110029 .int -(0x1BADB002 + 0x00000007) # checksum
2110030 #
2110031 # Here starts really the code.
2110032 #
2110033 start:
2110034 #
2110035 # Set ESP at the stack bottom.
2110036 #
2110037 movl $_k_stack_bottom, %esp
2110038 #
2110039 # Reset flags inside EFLAGS, but must use the stack
2110040 # to make it.
2110041 #
2110042 pushl $0
2110043 popf
2110044 #
2110045 # Call function `kmain()'. It is not the usual
2110046 # `main()' because we need to pass some data, but
2110047 # it is not compatible with the
2110048 # standard `main()' prototype.
2110049 #
2110050 # void kmain (uint32_t magic, multiboot_t *info);
2110051 #
2110052 pushl %ebx # Pointer to the structure containing
2110053 # data from the boot system.
2110054 pushl %eax # Boot system signature.
2110055 #
2110056 call kmain # Do the call.
2110057 #
2110058 # Halt procedure.
2110059 #
2110060 halt:
2110061 hlt # If the function `kmain()' return, this
2110062 # instruction will halt the CPU.
2110063 jmp halt # If the CPU will resume working, the
2110064 # HLT instruction will be repeated.
2110065 #------------------------------------------------------
2110066 .align 4
2110067 .section .data
2110068 #------------------------------------------------------
2110069 .align 4
2110070 .section .bss
2110071 #------------------------------------------------------
|
|
94.9.3
kernel/main/kmain.c
Si veda la sezione 93.13.
2120001 #include <kernel/main.h>
2120002 #include <kernel/main/build.h>
2120003 #include <kernel/lib_k.h>
2120004 #include <kernel/driver/tty.h>
2120005 #include <kernel/memory.h>
2120006 #include <stdlib.h>
2120007 #include <stdint.h>
2120008 #include <kernel/driver/screen.h>
2120009 #include <kernel/proc.h>
2120010 #include <kernel/lib_s.h>
2120011 #include <kernel/fs.h>
2120012 #include <unistd.h>
2120013 #include <stdint.h>
2120014 #include <kernel/driver/kbd.h>
2120015 #include <kernel/driver/ata.h>
2120016 #include <kernel/dev.h>
2120017 #include <kernel/blk.h>
2120018 #include <fcntl.h>
2120019 #include <string.h>
2120020 #include <limits.h>
2120021 #include <kernel/driver/pci.h>
2120022 #include <kernel/net/icmp.h>
2120023 #include <kernel/net/arp.h>
2120024 #include <kernel/net/route.h>
2120025 #include <kernel/net/tcp.h>
2120026 #include <kernel/driver/nic/ne2k.h>
2120027 #include <errno.h>
2120028 //----------------------------------------------------------
2120029 static char command[MAX_CANON];
2120030 //----------------------------------------------------------
2120031 void
2120032 kmain (uint32_t magic, multiboot_t * mboot_data)
2120033 {
2120034 int exit;
2120035 pid_t pid;
2120036 int counter;
2120037 char *exec_argv[2];
2120038 int status;
2120039 ssize_t count;
2120040 //
2120041 // 0xAC15FEFE == 172.21.254.254
2120042 //
2120043 h_addr_t ip_to_be_found = 0xAC15FEFE;
2120044 //
2120045 // Reset video and select the initial console.
2120046 //
2120047 tty_init ();
2120048 //
2120049 // Verify `multiboot' data.
2120050 //
2120051 if (magic == 0x2BADB002)
2120052 {
2120053 //
2120054 // Save multiboot data.
2120055 //
2120056 mboot_save (mboot_data);
2120057 //
2120058 // Show compilation date and time, plus upper
2120059 // memory limit.
2120060 //
2120061 k_printf ("os32 build %s ram %i Kibyte\n",
2120062 BUILD_DATE, (int) multiboot.mem_upper);
2120063 //
2120064 // Show also the command line.
2120065 //
2120066 k_printf ("%s\n", multiboot.cmdline);
2120067 //
2120068 // Set `mb_max', for memory allocation.
2120069 //
2120070 mb_size (multiboot.mem_upper * 1024);
2120071 //
2120072 // keyboard initialization.
2120073 //
2120074 kbd_load ();
2120075 //
2120076 // Block cache initialization.
2120077 //
2120078 blk_cache_init ();
2120079 //
2120080 // PCI bus initialization.
2120081 //
2120082 pci_init ();
2120083 //
2120084 // File system management initialization.
2120085 //
2120086 fs_init ();
2120087 //
2120088 // Set up processes.
2120089 //
2120090 proc_init ();
2120091 //
2120092 // Set up network.
2120093 //
2120094 net_init ();
2120095 }
2120096 else
2120097 {
2120098 //
2120099 // If it is not a multiboot loader, it is an
2120100 // error.
2120101 //
2120102 k_printf
2120103 ("os32 build %s. ERROR. no "
2120104 "\"multiboot\" header!\n", BUILD_DATE);
2120105 k_printf ("[%s] system halted\n", __func__);
2120106 k_exit ();
2120107 }
2120108 //
2120109 // The kernel will run interactively.
2120110 //
2120111 k_printf
2120112 (".---------------------------------------------------."
2120113 "\n"
2120114 "| `h' followed by [Enter] to show a menu |"
2120115 "\n"
2120116 "`---------------------------------------------------'"
2120117 "\n");
2120118 // menu ();
2120119 //
2120120 //
2120121 //
2120122 for (exit = 0; exit == 0;)
2120123 {
2120124 //
2120125 // While in kernel code, timer interrupt don't
2120126 // start the
2120127 // scheduler. The kernel must leave control to
2120128 // the scheduler
2120129 // via a null system call.
2120130 //
2120131 sys (SYS_0, NULL, 0);
2120132 //
2120133 // Back to work: read the keyboard from the TTY
2120134 // device.
2120135 //
2120136 count =
2120137 dev_io ((pid_t) 0, (dev_t) DEV_TTY, DEV_READ,
2120138 (off_t) 0, command, (size_t) MAX_CANON,
2120139 NULL);
2120140 //
2120141 // Check if there is a command: the kernel does
2120142 // not
2120143 // go to sleep.
2120144 //
2120145 if (count < 0)
2120146 {
2120147 if (errno == EAGAIN)
2120148 {
2120149 //
2120150 // No command is ready in the buffer
2120151 // keyboard.
2120152 //
2120153 continue;
2120154 }
2120155 else
2120156 {
2120157 k_perror (NULL);
2120158 continue;
2120159 }
2120160 }
2120161 if (count == 0)
2120162 {
2120163 //
2120164 // No command is ready in the buffer
2120165 // keyboard.
2120166 //
2120167 continue;
2120168 }
2120169 if (count == 1)
2120170 {
2120171 //
2120172 // Just [Enter] was pressed.
2120173 //
2120174 continue;
2120175 }
2120176 if (count > MAX_CANON)
2120177 {
2120178 //
2120179 // Something impossible!
2120180 //
2120181 continue;
2120182 }
2120183 //
2120184 // The last character is the "line delimiter"
2120185 // (new line et al.),
2120186 // or zero in case of EOF. The last character is
2120187 // replaced with
2120188 // zero, so that the command becomes a
2120189 // terminated string.
2120190 //
2120191 command[count - 1] = 0;
2120192 //
2120193 // A command was typed: start to check what it
2120194 // was.
2120195 //
2120196 if (strncmp (command, "1", MAX_CANON) == 0)
2120197 {
2120198 //
2120199 // Kill init.
2120200 //
2120201 s_kill ((pid_t) 0, (pid_t) 1, SIGKILL);
2120202 }
2120203 else if (strncmp (command, "2", MAX_CANON) == 0)
2120204 {
2120205 //
2120206 // Kill proc. 2
2120207 //
2120208 s_kill ((pid_t) 0, (pid_t) 2, SIGTERM);
2120209 }
2120210 else if (strncmp (command, "3", MAX_CANON) == 0)
2120211 {
2120212 //
2120213 // Kill proc. 3
2120214 //
2120215 s_kill ((pid_t) 0, (pid_t) 3, SIGTERM);
2120216 }
2120217 else if (strncmp (command, "4", MAX_CANON) == 0)
2120218 {
2120219 //
2120220 // Kill proc. 4
2120221 //
2120222 s_kill ((pid_t) 0, (pid_t) 4, SIGTERM);
2120223 }
2120224 else if (strncmp (command, "5", MAX_CANON) == 0)
2120225 {
2120226 //
2120227 // Kill proc. 5
2120228 //
2120229 s_kill ((pid_t) 0, (pid_t) 5, SIGTERM);
2120230 }
2120231 else if (strncmp (command, "6", MAX_CANON) == 0)
2120232 {
2120233 //
2120234 // Kill proc. 6
2120235 //
2120236 s_kill ((pid_t) 0, (pid_t) 6, SIGTERM);
2120237 }
2120238 else if (strncmp (command, "7", MAX_CANON) == 0)
2120239 {
2120240 //
2120241 // Kill proc. 7
2120242 //
2120243 s_kill ((pid_t) 0, (pid_t) 7, SIGTERM);
2120244 }
2120245 else if (strncmp (command, "8", MAX_CANON) == 0)
2120246 {
2120247 //
2120248 // Kill proc. 8
2120249 //
2120250 s_kill ((pid_t) 0, (pid_t) 8, SIGTERM);
2120251 }
2120252 else if (strncmp (command, "9", MAX_CANON) == 0)
2120253 {
2120254 //
2120255 // Kill proc. 9
2120256 //
2120257 s_kill ((pid_t) 0, (pid_t) 9, SIGTERM);
2120258 }
2120259 else if (strncmp (command, "A", MAX_CANON) == 0)
2120260 {
2120261 //
2120262 // Kill proc. 10
2120263 //
2120264 s_kill ((pid_t) 0, (pid_t) 10, SIGTERM);
2120265 }
2120266 else if (strncmp (command, "B", MAX_CANON) == 0)
2120267 {
2120268 //
2120269 // Kill proc. 11
2120270 //
2120271 s_kill ((pid_t) 0, (pid_t) 11, SIGTERM);
2120272 }
2120273 else if (strncmp (command, "C", MAX_CANON) == 0)
2120274 {
2120275 //
2120276 // Kill proc. 12
2120277 //
2120278 s_kill ((pid_t) 0, (pid_t) 12, SIGTERM);
2120279 }
2120280 else if (strncmp (command, "D", MAX_CANON) == 0)
2120281 {
2120282 //
2120283 // Kill proc. 13
2120284 //
2120285 s_kill ((pid_t) 0, (pid_t) 13, SIGTERM);
2120286 }
2120287 else if (strncmp (command, "E", MAX_CANON) == 0)
2120288 {
2120289 //
2120290 // Kill proc. 14
2120291 //
2120292 s_kill ((pid_t) 0, (pid_t) 14, SIGTERM);
2120293 }
2120294 else if (strncmp (command, "F", MAX_CANON) == 0)
2120295 {
2120296 //
2120297 // Kill proc. 15
2120298 //
2120299 s_kill ((pid_t) 0, (pid_t) 15, SIGTERM);
2120300 }
2120301 else if (strncmp (command, "a", MAX_CANON) == 0)
2120302 {
2120303 run ("/bin/aaa", NULL, NULL);
2120304 }
2120305 else if (strncmp (command, "b", MAX_CANON) == 0)
2120306 {
2120307 run ("/bin/bbb", NULL, NULL);
2120308 }
2120309 else if (strncmp (command, "c", MAX_CANON) == 0)
2120310 {
2120311 run ("/bin/ccc", NULL, NULL);
2120312 }
2120313 else if (strncmp (command, "f", MAX_CANON) == 0)
2120314 {
2120315 pid = fork ();
2120316 if (pid == -1)
2120317 {
2120318 k_perror (NULL);
2120319 }
2120320 else if (pid == 0)
2120321 {
2120322 //
2120323 // Get child real pid.
2120324 //
2120325 pid = getpid ();
2120326 //
2120327 // Please note that the child is no more
2120328 // a kernel, and can access to process
2120329 // system calls.
2120330 //
2120331 for (counter = 0; counter < 60; counter++)
2120332 {
2120333 z_printf ("%1x", (int) pid);
2120334 sleep (1);
2120335 }
2120336 }
2120337 else
2120338 {
2120339 z_printf ("io sono il genitore di %i\n", pid);
2120340 }
2120341 }
2120342 else if (strncmp (command, "g", MAX_CANON) == 0)
2120343 {
2120344 gdt_print (&gdt_register, 0, 20);
2120345 }
2120346 else if (strncmp (command, "G", MAX_CANON) == 0)
2120347 {
2120348 gdt_print (&gdt_register, 21, 41);
2120349 }
2120350 else if (strncmp (command, "h", MAX_CANON) == 0)
2120351 {
2120352 menu ();
2120353 }
2120354 else if (strncmp (command, "i", MAX_CANON) == 0)
2120355 {
2120356 idt_print (&idt_register, 0, 20);
2120357 }
2120358 else if (strncmp (command, "I", MAX_CANON) == 0)
2120359 {
2120360 idt_print (&idt_register, 21, 41);
2120361 }
2120362 else if (strncmp (command, "m", MAX_CANON) == 0)
2120363 {
2120364 mb_print ();
2120365 }
2120366 else if (strncmp (command, "n", MAX_CANON) == 0)
2120367 {
2120368 inode_print ();
2120369 }
2120370 else if (strncmp (command, "p", MAX_CANON) == 0)
2120371 {
2120372 proc_print ();
2120373 }
2120374 else if (strncmp (command, "s", MAX_CANON) == 0)
2120375 {
2120376 sb_print ();
2120377 }
2120378 else if (strncmp (command, "t", MAX_CANON) == 0)
2120379 {
2120380 k_printf ("clock: %lli time: %i\n",
2120381 (long long int) k_clock (),
2120382 (int) k_time (NULL));
2120383 }
2120384 else if (strncmp (command, "T", MAX_CANON) == 0)
2120385 {
2120386 while (1)
2120387 {
2120388 k_printf ("clock: %lli time: %i\n",
2120389 (long long int) k_clock (),
2120390 (int) k_time (NULL));
2120391 }
2120392 }
2120393 else if (strncmp (command, "w", MAX_CANON) == 0)
2120394 {
2120395 status = s_open ((pid_t) 0, "/tmp/test",
2120396 O_WRONLY | O_CREAT |
2120397 O_TRUNC, 0644);
2120398 //
2120399 if (status >= 0)
2120400 {
2120401 status = s_close ((pid_t) 0, status);
2120402 if (status != 0)
2120403 {
2120404 k_perror (NULL);
2120405 }
2120406 }
2120407 }
2120408 else if (strncmp (command, "x", MAX_CANON) == 0)
2120409 {
2120410 //
2120411 // Load init.
2120412 //
2120413 exec_argv[0] = "/bin/init";
2120414 exec_argv[1] = NULL;
2120415 pid = run ("/bin/init", exec_argv, NULL);
2120416 //
2120417 // Just sleep.
2120418 //
2120419 while (1)
2120420 {
2120421 sys (SYS_0, NULL, 0);
2120422 }
2120423 }
2120424 else if (strncmp (command, "q", MAX_CANON) == 0)
2120425 {
2120426 k_printf ("System halted!\n");
2120427 return;
2120428 }
2120429 else if (strncmp (command, "y", MAX_CANON) == 0)
2120430 {
2120431 // icmp_test3 ();
2120432 // icmp_test2 ();
2120433 // ip_test2 ();
2120434 // ip_test ();
2120435 tcp_test ();
2120436 }
2120437 else if (strncmp (command, "r", MAX_CANON) == 0)
2120438 {
2120439 arp_print ();
2120440 }
2120441 else if (strncmp (command, "R", MAX_CANON) == 0)
2120442 {
2120443 arp_request (ip_to_be_found);
2120444 }
2120445 }
2120446 }
|
|
94.9.4
kernel/main/menu.c
Si veda la sezione 93.13.
2130001 #include <kernel/main.h>
2130002 #include <kernel/lib_k.h>
2130003 //----------------------------------------------------------
2130004 void
2130005 menu (void)
2130006 {
2130007 k_printf
2130008 (".---------------------------------------------------."
2130009 "\n"
2130010 "| h show this menu .-----------.|"
2130011 "\n"
2130012 "| t show internal timer values |all ||"
2130013 "\n"
2130014 "| f fork the kernel |commands ||"
2130015 "\n"
2130016 "| m memory map (HEX) |followed ||"
2130017 "\n"
2130018 "| g|G show GDT table first 21+21 items|by [Enter] ||"
2130019 "\n"
2130020 "| i|I show IDT table first 21+21 items`-----------'|"
2130021 "\n"
2130022 "| p process status list |"
2130023 "\n"
2130024 "| s super block list |"
2130025 "\n"
2130026 "| n list of active inodes |"
2130027 "\n"
2130028 "| 1..9 kill process 1 to 9 |"
2130029 "\n"
2130030 "| A..F kill process 10 to 15 |"
2130031 "\n"
2130032 "| a..c run programs `/bin/aaa' to `/bin/ccc' |"
2130033 "\n"
2130034 "| in paralel |"
2130035 "\n"
2130036 "| r ARP table |"
2130037 "\n"
2130038 "| x exit kernel interaction, start `/bin/init' |"
2130039 "\n"
2130040 "| q quit kernel |"
2130041 "\n"
2130042 "`---------------------------------------------------'"
2130043 "\n");
2130044 }
|
|
94.9.5
kernel/main/run.c
Si veda la sezione 93.13.
2140001 #include <kernel/main.h>
2140002 #include <kernel/proc.h>
2140003 #include <kernel/lib_k.h>
2140004 #include <unistd.h>
2140005 //----------------------------------------------------------
2140006 pid_t
2140007 run (char *path, char *argv[], char *envp[])
2140008 {
2140009 pid_t pid;
2140010 //
2140011 pid = fork ();
2140012 if (pid == -1)
2140013 {
2140014 k_perror (NULL);
2140015 }
2140016 else if (pid == 0)
2140017 {
2140018 execve (path, argv, envp);
2140019 z_perror (NULL);
2140020 _exit (0);
2140021 }
2140022 return (pid);
2140023 }
|
|
94.9.6
kernel/main/stack.s
Si veda la sezione 93.13.
2150001 .global _k_stack_top
2150002 .global _k_stack_bottom
2150003 #######################################################
2150004 #
2150005 # Kernel stack size. The value 0x010000 is equal to
2150006 # 1 Mibyte.
2150007 # Please note that if the kernel stack is too little,
2150008 # there is no way to check it.
2150009 #
2150010 .equ STACK_SIZE, 0x0100000
2150011 #------------------------------------------------------
2150012 .align 4
2150013 .section .bss
2150014 #------------------------------------------------------
2150015 #
2150016 # At the end is placed the space for the kernel stack,
2150017 # with no initialization.
2150018 #
2150019 _k_stack_top:
2150020 .space STACK_SIZE
2150021 _k_stack_bottom:
2150022 #------------------------------------------------------
|
|
94.10
os32: «kernel/memory.h»
Si veda la sezione 93.14.
2160001 #ifndef _KERNEL_MEMORY_H
2160002 #define _KERNEL_MEMORY_H 1
2160003 //----------------------------------------------------------
2160004 #include <stdint.h>
2160005 #include <stddef.h>
2160006 #include <sys/types.h>
2160007 //----------------------------------------------------------
2160008 #define MEM_BLOCK_SIZE 0x1000 // 4 Ki/block
2160009 #define MEM_MAX_BLOCKS 0x100000 // 1 Mi blocks
2160010 // = 4 Gibyte
2160011
2160012 extern uint32_t mb_table[MEM_MAX_BLOCKS / 32]; // [1]
2160013 //
2160014 // [1] Memory blocks map.
2160015 //
2160016 extern unsigned int mb_max; // Memory blocks max.
2160017 //----------------------------------------------------------
2160018 typedef unsigned int addr_t;
2160019 //----------------------------------------------------------
2160020 uint32_t *mb_reference (void);
2160021 ssize_t mb_alloc (addr_t address, size_t size);
2160022 void mb_free (addr_t address, size_t size);
2160023 int mb_reduce (addr_t address, size_t new, size_t previous);
2160024 void mb_clean (addr_t address, size_t size);
2160025 addr_t mb_alloc_size (size_t size);
2160026 void mb_print (void);
2160027 void mb_size (size_t size);
2160028 //----------------------------------------------------------
2160029 #endif
|
|
94.10.1
kernel/memory/mb_alloc.c
Si veda la sezione 93.14.
2170001 #include <kernel/memory.h>
2170002 #include <kernel/ibm_i386.h>
2170003 #include <sys/os32.h>
2170004 #include <kernel/lib_k.h>
2170005 //----------------------------------------------------------
2170006 #define DEBUG 0
2170007 //----------------------------------------------------------
2170008 static int mb_block_set1 (int block);
2170009 //----------------------------------------------------------
2170010 ssize_t
2170011 mb_alloc (addr_t address, size_t size)
2170012 {
2170013 unsigned int bstart;
2170014 unsigned int bsize;
2170015 unsigned int bend;
2170016 unsigned int i;
2170017 ssize_t allocated = 0;
2170018 addr_t block_address;
2170019 //
2170020 if (size == 0)
2170021 {
2170022 //
2170023 // Zero means nothing.
2170024 //
2170025 allocated = 0;
2170026 return (allocated);
2170027 }
2170028 //
2170029 // Show what was requested.
2170030 //
2170031 if (DEBUG)
2170032 {
2170033 k_printf ("%s(%i, %zi)", __func__,
2170034 (unsigned int) address, size);
2170035 }
2170036 //
2170037 // Calculate starting block of memory.
2170038 //
2170039 bstart = address / MEM_BLOCK_SIZE;
2170040 //
2170041 // Calculating size in term of blocks.
2170042 //
2170043 if (size % MEM_BLOCK_SIZE)
2170044 {
2170045 bsize = size / MEM_BLOCK_SIZE + 1;
2170046 }
2170047 else
2170048 {
2170049 bsize = size / MEM_BLOCK_SIZE;
2170050 }
2170051 //
2170052 // Calculate the block number after the
2170053 // end of the requested memory area.
2170054 //
2170055 bend = bstart + bsize;
2170056 //
2170057 // Scan the memory map and allocate.
2170058 //
2170059 for (i = bstart; i < bend; i++)
2170060 {
2170061 if (mb_block_set1 (i))
2170062 {
2170063 allocated += MEM_BLOCK_SIZE;
2170064 }
2170065 else
2170066 {
2170067 block_address = i;
2170068 block_address *= MEM_BLOCK_SIZE;
2170069 k_printf
2170070 ("[%s] Kernel alert: mem block "
2170071 "%x, at address "
2170072 "%x, already allocated!\n", __FILE__, i,
2170073 (unsigned int) block_address);
2170074 break;
2170075 }
2170076 }
2170077 //
2170078 //
2170079 //
2170080 return (allocated);
2170081 }
2170082
2170083 //----------------------------------------------------------
2170084 static int
2170085 mb_block_set1 (int block)
2170086 {
2170087 int i = block / 32;
2170088 int j = block % 32;
2170089 uint32_t mask = 0x80000000 >> j;
2170090 if (mb_table[i] & mask)
2170091 {
2170092 return (0); // The block is already set to
2170093 // 1 inside the map!
2170094 }
2170095 else
2170096 {
2170097 mb_table[i] = mb_table[i] | mask;
2170098 return (1);
2170099 }
2170100 }
|
|
94.10.2
kernel/memory/mb_alloc_size.c
Si veda la sezione 93.14.
2180001 #include <kernel/memory.h>
2180002 #include <kernel/ibm_i386.h>
2180003 #include <kernel/lib_k.h>
2180004 #include <sys/os32.h>
2180005 #include <errno.h>
2180006 //----------------------------------------------------------
2180007 #define DEBUG 0
2180008 //----------------------------------------------------------
2180009 static int mb_block_status (int block);
2180010 //----------------------------------------------------------
2180011 addr_t
2180012 mb_alloc_size (size_t size)
2180013 {
2180014 unsigned int bsize;
2180015 unsigned int i;
2180016 unsigned int j;
2180017 unsigned int found = 0;
2180018 addr_t alloc_addr;
2180019 ssize_t alloc_size;
2180020 //
2180021 //
2180022 //
2180023 if (size == 0)
2180024 {
2180025 errset (EINVAL);
2180026 return ((addr_t) 0);
2180027 }
2180028 //
2180029 // Show what was requested.
2180030 //
2180031 if (DEBUG)
2180032 {
2180033 k_printf ("%s(%zi)", __func__, size);
2180034 }
2180035 //
2180036 // Calculate block size.
2180037 //
2180038 if (size % MEM_BLOCK_SIZE)
2180039 {
2180040 bsize = size / MEM_BLOCK_SIZE + 1;
2180041 }
2180042 else
2180043 {
2180044 bsize = size / MEM_BLOCK_SIZE;
2180045 }
2180046 //
2180047 // Scan for a contiguous space in memory.
2180048 //
2180049 for (i = 0; i < (mb_max - bsize) && !found; i++)
2180050 {
2180051 for (j = 0; j < bsize; j++)
2180052 {
2180053 found = !mb_block_status (i + j);
2180054 if (!found)
2180055 {
2180056 i += j;
2180057 break;
2180058 }
2180059 }
2180060 }
2180061 //
2180062 // If the space was found, allocate it.
2180063 //
2180064 if (found && (j == bsize))
2180065 {
2180066 alloc_addr = i - 1;
2180067 alloc_addr *= MEM_BLOCK_SIZE;
2180068 alloc_size = bsize * MEM_BLOCK_SIZE;
2180069 alloc_size =
2180070 mb_alloc (alloc_addr, (size_t) alloc_size);
2180071 //
2180072 if (alloc_size <= 0)
2180073 {
2180074 errset (ENOMEM);
2180075 return ((addr_t) 0);
2180076 }
2180077 else if (alloc_size < size)
2180078 {
2180079 mb_free (alloc_addr, (size_t) alloc_size);
2180080 errset (ENOMEM);
2180081 return ((addr_t) 0);
2180082 }
2180083 else
2180084 {
2180085 //
2180086 // Clean memory before return.
2180087 //
2180088 mb_clean (alloc_addr, (size_t) alloc_size);
2180089 //
2180090 //
2180091 //
2180092 return (alloc_addr);
2180093 }
2180094 }
2180095 else
2180096 {
2180097 errset (ENOMEM);
2180098 return ((addr_t) 0);
2180099 }
2180100 }
2180101
2180102 //----------------------------------------------------------
2180103 static int
2180104 mb_block_status (int block)
2180105 {
2180106 int i = block / 32;
2180107 int j = block % 32;
2180108 uint32_t mask = 0x80000000 >> j;
2180109 return ((int) (mb_table[i] & mask));
2180110 }
|
|
94.10.3
kernel/memory/mb_clean.c
Si veda la sezione 93.14.
2190001 #include <kernel/memory.h>
2190002 //----------------------------------------------------------
2190003 void
2190004 mb_clean (addr_t address, size_t size)
2190005 {
2190006 unsigned int i;
2190007 char *mem;
2190008 //
2190009 mem = (char *) address;
2190010 //
2190011 for (i = 0; i < size; i++)
2190012 {
2190013 mem[i] = 0;
2190014 }
2190015 }
|
|
94.10.4
kernel/memory/mb_free.c
Si veda la sezione 93.14.
2200001 #include <kernel/memory.h>
2200002 #include <kernel/ibm_i386.h>
2200003 #include <sys/os32.h>
2200004 #include <kernel/lib_k.h>
2200005 //----------------------------------------------------------
2200006 #define DEBUG 0
2200007 //----------------------------------------------------------
2200008 static int mb_block_set0 (int block);
2200009 //----------------------------------------------------------
2200010 void
2200011 mb_free (addr_t address, size_t size)
2200012 {
2200013 unsigned int bstart;
2200014 unsigned int bsize;
2200015 unsigned int bend;
2200016 unsigned int i;
2200017 addr_t block_address;
2200018 //
2200019 // k_printf ("releasing 0x%x, size 0x%x\n", (int)
2200020 // address,
2200021 // (int) size);
2200022 //
2200023 if (size == 0)
2200024 {
2200025 //
2200026 // Zero means nothing.
2200027 //
2200028 return;
2200029 }
2200030 //
2200031 // Show what was requested.
2200032 //
2200033 if (DEBUG)
2200034 {
2200035 k_printf ("%s(%i, %zi)", __func__,
2200036 (unsigned int) address, size);
2200037 }
2200038 //
2200039 // Calculate size in term of blocks.
2200040 //
2200041 if (size % MEM_BLOCK_SIZE)
2200042 {
2200043 bsize = size / MEM_BLOCK_SIZE + 1;
2200044 }
2200045 else
2200046 {
2200047 bsize = size / MEM_BLOCK_SIZE;
2200048 }
2200049 //
2200050 // Calculate start address in term of blocks.
2200051 //
2200052 bstart = address / MEM_BLOCK_SIZE;
2200053 //
2200054 // Calculate end address, in term of blocks.
2200055 // This address is after the memory area to
2200056 // be released.
2200057 //
2200058 bend = bstart + bsize;
2200059 //
2200060 // Scan the memory map to free memory blocks.
2200061 //
2200062 for (i = bstart; i < bend; i++)
2200063 {
2200064 if (mb_block_set0 (i))
2200065 {
2200066 ;
2200067 }
2200068 else
2200069 {
2200070 block_address = i;
2200071 block_address *= MEM_BLOCK_SIZE;
2200072 k_printf
2200073 ("[%s] Kernel alert: mem block "
2200074 "0x%x, at address "
2200075 "0x%x, already released!\n", __FILE__, i,
2200076 (unsigned int) block_address);
2200077 }
2200078 }
2200079 }
2200080
2200081 //----------------------------------------------------------
2200082 static int
2200083 mb_block_set0 (int block)
2200084 {
2200085 int i = block / 32;
2200086 int j = block % 32;
2200087 uint32_t mask = 0x80000000 >> j;
2200088 if (mb_table[i] & mask)
2200089 {
2200090 mb_table[i] = mb_table[i] & ~mask;
2200091 return (1);
2200092 }
2200093 else
2200094 {
2200095 return (0); // The block is already set to
2200096 // 0 inside the map!
2200097 }
2200098 }
|
|
94.10.5
kernel/memory/mb_print.c
Si veda la sezione 93.14.
2210001 #include <kernel/memory.h>
2210002 #include <kernel/ibm_i386.h>
2210003 #include <sys/os32.h>
2210004 #include <kernel/lib_k.h>
2210005 #include <kernel/multiboot.h>
2210006 //----------------------------------------------------------
2210007 void
2210008 mb_print (void)
2210009 {
2210010 unsigned int block;
2210011 unsigned int blocks =
2210012 (multiboot.mem_upper * 1024 / MEM_BLOCK_SIZE);
2210013 int i;
2210014 int j;
2210015 uint32_t mask;
2210016 unsigned int start = 0;
2210017 unsigned int stop = 0;
2210018 unsigned int status = 0;
2210019 //
2210020 k_printf ("Hex mem map, blocks of %x:", MEM_BLOCK_SIZE);
2210021 //
2210022 for (block = 0; block < blocks; block++)
2210023 {
2210024 i = block / 32;
2210025 j = block % 32;
2210026 mask = 0x80000000 >> j;
2210027 if (mb_table[i] & mask)
2210028 {
2210029 //
2210030 // Allocated block
2210031 //
2210032 if (status == 0)
2210033 {
2210034 status = 1;
2210035 start = block;
2210036 }
2210037 }
2210038 else
2210039 {
2210040 //
2210041 // Not allocated block.
2210042 //
2210043 if (status == 1)
2210044 {
2210045 status = 0;
2210046 stop = block;
2210047 }
2210048 }
2210049 //
2210050 //
2210051 //
2210052 if (stop > 0)
2210053 {
2210054 k_printf (" %x-%x", start, stop);
2210055 start = 0;
2210056 stop = 0;
2210057 }
2210058 }
2210059 k_printf ("\n");
2210060 }
|
|
94.10.6
kernel/memory/mb_public.c
Si veda la sezione 93.14.
2220001 #include <kernel/memory.h>
2220002 #include <stdint.h>
2220003 //----------------------------------------------------------
2220004 uint32_t mb_table[MEM_MAX_BLOCKS / 32]; // Memory
2220005 // blocks map.
2220006 unsigned int mb_max = MEM_MAX_BLOCKS; // Memory
2220007 // blocks max.
2220008 //----------------------------------------------------------
|
|
94.10.7
kernel/memory/mb_reduce.c
Si veda la sezione 93.14.
2230001 #include <kernel/memory.h>
2230002 #include <kernel/ibm_i386.h>
2230003 #include <sys/os32.h>
2230004 #include <errno.h>
2230005 //----------------------------------------------------------
2230006 int
2230007 mb_reduce (addr_t address, size_t new, size_t previous)
2230008 {
2230009 addr_t start;
2230010 addr_t end;
2230011 size_t size;
2230012 //
2230013 //
2230014 //
2230015 if (new > previous)
2230016 {
2230017 //
2230018 // We are reducing, not extending!
2230019 //
2230020 errset (EINVAL);
2230021 return (-1);
2230022 }
2230023 //
2230024 //
2230025 //
2230026 if (new == previous)
2230027 {
2230028 //
2230029 // Nothing to do.
2230030 //
2230031 return (0);
2230032 }
2230033 //
2230034 // Correct sizes to conform to memory blocks.
2230035 //
2230036 start = address + new;
2230037 if (start % MEM_BLOCK_SIZE)
2230038 {
2230039 start /= MEM_BLOCK_SIZE;
2230040 start++;
2230041 start *= MEM_BLOCK_SIZE;
2230042 }
2230043 //
2230044 end = address + previous;
2230045 end /= MEM_BLOCK_SIZE;
2230046 end *= MEM_BLOCK_SIZE;
2230047 //
2230048 size = end - start;
2230049 //
2230050 // Finally release the extra memory, no more used.
2230051 //
2230052 mb_free (start, size);
2230053 //
2230054 // Ok.
2230055 //
2230056 return (0);
2230057 }
|
|
94.10.8
kernel/memory/mb_reference.c
Si veda la sezione 93.14.
2240001 #include <stdint.h>
2240002 #include <kernel/memory.h>
2240003 //----------------------------------------------------------
2240004 uint32_t *
2240005 mb_reference (void)
2240006 {
2240007 return mb_table;
2240008 }
|
|
94.10.9
kernel/memory/mb_size.c
Si veda la sezione 93.14.
2250001 #include <kernel/memory.h>
2250002 //----------------------------------------------------------
2250003 void
2250004 mb_size (size_t size)
2250005 {
2250006 mb_max = size / MEM_BLOCK_SIZE;
2250007 }
|
|
94.11
os32: «kernel/multiboot.h»
Si veda la sezione 93.15.
2260001 #ifndef _KERNEL_MULTIBOOT_H
2260002 #define _KERNEL_MULTIBOOT_H 1
2260003 //----------------------------------------------------------
2260004 #include <inttypes.h>
2260005 //----------------------------------------------------------
2260006 #define MBOOT_CMDLINE_MAX 4096
2260007 #define MBOOT_CMDLINE_OPTION_MAX 1024
2260008 #define MBOOT_CMDLINE_ARGUMENTS_MAX 32
2260009 //----------------------------------------------------------
2260010 typedef struct
2260011 {
2260012 uint32_t flags;
2260013 uint32_t mem_lower;
2260014 uint32_t mem_upper;
2260015 uint32_t boot_device;
2260016 char *cmdline;
2260017 } multiboot_t;
2260018 //
2260019 typedef struct
2260020 {
2260021 uint32_t flags;
2260022 uint32_t mem_lower;
2260023 uint32_t mem_upper;
2260024 uint32_t boot_device;
2260025 char cmdline[MBOOT_CMDLINE_MAX];
2260026 } multiboot_save_t;
2260027 //
2260028 extern multiboot_save_t multiboot;
2260029 //----------------------------------------------------------
2260030 void mboot_save (multiboot_t * mboot_data);
2260031 char **mboot_cmdline_opt (const char *opt,
2260032 const char *delim);
2260033 //----------------------------------------------------------
2260034 #endif
|
|
94.11.1
kernel/multiboot/mboot_cmdline_opt.c
Si veda la sezione 93.15.
2270001 #include <stddef.h>
2270002 #include <kernel/multiboot.h>
2270003 #include <kernel/lib_k.h>
2270004 #include <string.h>
2270005 #include <errno.h>
2270006 //----------------------------------------------------------
2270007 char **
2270008 mboot_cmdline_opt (const char *opt, const char *delim)
2270009 {
2270010 static char option[MBOOT_CMDLINE_OPTION_MAX];
2270011 static char *argument[MBOOT_CMDLINE_ARGUMENTS_MAX];
2270012 char *a;
2270013 char *z;
2270014 char *t;
2270015 int i;
2270016 size_t size;
2270017 //
2270018 // Check input.
2270019 //
2270020 if (opt == NULL)
2270021 {
2270022 errset (EINVAL);
2270023 return (NULL);
2270024 }
2270025 //
2270026 // Find the option.
2270027 //
2270028 a = strstr (multiboot.cmdline, opt);
2270029 if (a == NULL)
2270030 {
2270031 return (NULL);
2270032 }
2270033 //
2270034 // Find the end of the option: might be a space or
2270035 // the end of the
2270036 // string.
2270037 //
2270038 z = strpbrk (a, " \t\n");
2270039 //
2270040 // Copy the option inside the static array
2270041 // `option[]'.
2270042 //
2270043 if (z == NULL)
2270044 {
2270045 strncpy (option, a, MBOOT_CMDLINE_OPTION_MAX - 1);
2270046 option[MBOOT_CMDLINE_OPTION_MAX - 1] = 0;
2270047 }
2270048 else
2270049 {
2270050 size = (uintptr_t) z - (uintptr_t) a;
2270051 strncpy (option, a, size);
2270052 option[size] = 0;
2270053 }
2270054 //
2270055 // Find the option name, to be saved as the first
2270056 // argument.
2270057 //
2270058 t = strtok (option, "=");
2270059 if (t == NULL)
2270060 {
2270061 errset (EUNKNOWN);
2270062 return (NULL);
2270063 }
2270064 argument[0] = t;
2270065 //
2270066 // If there is no delimiter, replace it with a
2270067 // string containing
2270068 // just a space.
2270069 //
2270070 if (delim == NULL)
2270071 {
2270072 delim = " ";
2270073 }
2270074 //
2270075 for (i = 1; i < MBOOT_CMDLINE_ARGUMENTS_MAX; i++)
2270076 {
2270077 t = strtok (NULL, delim);
2270078 if (t == NULL)
2270079 {
2270080 //
2270081 // The argument will be an empty string,
2270082 // taken from
2270083 // the end of the option string.
2270084 //
2270085 argument[i] =
2270086 &option[MBOOT_CMDLINE_OPTION_MAX - 1];
2270087 }
2270088 else
2270089 {
2270090 argument[i] = t;
2270091 }
2270092 }
2270093 //
2270094 // Return.
2270095 //
2270096 return (argument);
2270097 }
|
|
94.11.2
kernel/multiboot/mboot_public.c
Si veda la sezione 93.15.
2280001 #include <kernel/multiboot.h>
2280002 //----------------------------------------------------------
2280003 multiboot_save_t multiboot;
|
|
94.11.3
kernel/multiboot/mboot_save.c
Si veda la sezione 93.15.
2290001 #include <kernel/multiboot.h>
2290002 #include <string.h>
2290003 #include <kernel/lib_k.h>
2290004 //----------------------------------------------------------
2290005 void
2290006 mboot_save (multiboot_t * mboot_data)
2290007 {
2290008 multiboot.flags = mboot_data->flags;
2290009 //
2290010 if ((mboot_data->flags & 1) > 0)
2290011 {
2290012 multiboot.mem_lower = mboot_data->mem_lower;
2290013 multiboot.mem_upper = mboot_data->mem_upper;
2290014 }
2290015 if ((mboot_data->flags & 2) > 0)
2290016 {
2290017 multiboot.boot_device = mboot_data->boot_device;
2290018 }
2290019 if ((mboot_data->flags & 4) > 0)
2290020 {
2290021 strncpy (multiboot.cmdline, mboot_data->cmdline,
2290022 MBOOT_CMDLINE_MAX);
2290023 }
2290024 else
2290025 {
2290026 memset (multiboot.cmdline, 0, MBOOT_CMDLINE_MAX);
2290027 }
2290028 }
|
|
94.12
os32: «kernel/net.h»
Si veda la sezione 93.17.
2300001 #ifndef _KERNEL_NET_H
2300002 #define _KERNEL_NET_H 1
2300003 //----------------------------------------------------------
2300004 //
2300005 // WARNING: please remember to limit the max packets
2300006 // size to be transmitted, to a value that ensure no
2300007 // fragmentation at IPv4 level.
2300008 //
2300009 //----------------------------------------------------------
2300010 #include <stdint.h>
2300011 #include <sys/types.h>
2300012 #include <netinet/in.h>
2300013 #include <lib/sys/os32.h>
2300014 #include <netinet/ip.h>
2300015 #include <arpa/inet.h>
2300016 //----------------------------------------------------------
2300017 #define NET_PROT_IP 0x0800
2300018 #define NET_PROT_ARP 0x0806
2300019 #define NET_PROT_RARP 0x8035
2300020 //
2300021 #define NET_ETHERNET_ADDRESS_LENGTH 6
2300022 #define NET_IP_ADDRESS_LENGTH 4
2300023 //
2300024 #define NET_DEV_NULL 0x0000
2300025 #define NET_DEV_LOOP 0x0100
2300026 #define NET_DEV_LOOPBACK 0x0101
2300027 #define NET_DEV_ETH 0x0200
2300028 #define NET_DEV_ETH_NE2K 0x0201
2300029 //
2300030 #define NET_MAX_DEVICES 4
2300031 #define NET_MAX_BUFFERS 64
2300032 //
2300033 #define NET_ETHERNET_MIN_PACKET_SIZE 46
2300034 #define NET_ETHERNET_MAX_PACKET_SIZE 1500
2300035 #define NET_ETHERNET_HEADER_SIZE 14
2300036 #define NET_ETHERNET_MAX_FRAME_SIZE \
2300037 (NET_ETHERNET_MAX_PACKET_SIZE \
2300038 +NET_ETHERNET_HEADER_SIZE)
2300039 //
2300040 #define NET_IP_MIN_HEADER_SIZE 20
2300041 #define NET_IP_MIN_PACKET_SIZE 576
2300042 #define NET_IP_MAX_PACKET_SIZE \
2300043 NET_ETHERNET_MAX_PACKET_SIZE // [1]
2300044 #define NET_IP_MAX_DATA_SIZE \
2300045 (NET_IP_MAX_PACKET_SIZE \
2300046 -NET_IP_MIN_HEADER_SIZE)
2300047 //
2300048 // [1] The IP max packet size should be 65535, but as
2300049 // os32 does not accept fragmented packets, the
2300050 // maximum value depends on the Ethernet packet
2300051 // size. But this limitation might change, so
2300052 // there is also the value NET_MTU, that depends
2300053 // from the real physical network limitations.
2300054 //
2300055 #define NET_MTU NET_ETHERNET_MAX_PACKET_SIZE
2300056 //----------------------------------------------------------
2300057 //
2300058 // IP unfragmented packet, but it is not known if there
2300059 // are IP options, so it is not possible to define the
2300060 // space after the minimal header.
2300061 //
2300062 typedef union
2300063 {
2300064 uint8_t octet[NET_IP_MAX_PACKET_SIZE];
2300065 struct iphdr header;
2300066 } __attribute__ ((packed)) net_ip_packet_t;
2300067 //
2300068 // Ethernet header.
2300069 //
2300070 typedef struct
2300071 {
2300072 uint8_t dst[6];
2300073 uint8_t src[6];
2300074 uint16_t type;
2300075 } __attribute__ ((packed)) net_ethernet_header_t;
2300076 //
2300077 // Ethernet frame.
2300078 //
2300079 // .--------------------------------------------------.
2300080 // | . |
2300081 // |--------------------------------------------------|
2300082 // | .octet[] |
2300083 // |----------.---------------------------------------|
2300084 // | .header | .packet |
2300085 // |----------+---------------------------------------|
2300086 // | ... | .packet.octet[] |
2300087 // |----------+----------------.----------------------|
2300088 // | | .packet.header | / / / / // / / / / / |
2300089 // `----------'----------------'----------------------'
2300090 //
2300091 typedef union
2300092 {
2300093 //
2300094 uint8_t octet[NET_ETHERNET_MAX_FRAME_SIZE];
2300095 //
2300096 struct
2300097 {
2300098 net_ethernet_header_t header;
2300099 union
2300100 {
2300101 //
2300102 uint8_t octet[NET_IP_MAX_PACKET_SIZE];
2300103 //
2300104 struct iphdr header;
2300105 //
2300106 } __attribute__ ((packed)) packet;
2300107 } __attribute__ ((packed));
2300108 //
2300109 } __attribute__ ((packed)) net_ethernet_frame_t;
2300110 //----------------------------------------------------------
2300111 //
2300112 // Ethernet buffer.
2300113 //
2300114 typedef struct
2300115 {
2300116 clock_t clock;
2300117 size_t size;
2300118 net_ethernet_frame_t frame;
2300119 } __attribute__ ((packed)) net_buffer_eth_t;
2300120 //
2300121 // Loopback buffer.
2300122 //
2300123 typedef struct
2300124 {
2300125 clock_t clock;
2300126 size_t size;
2300127 union
2300128 {
2300129 uint8_t octet[NET_MTU];
2300130 struct iphdr header;
2300131 } packet;
2300132 } __attribute__ ((packed)) net_buffer_lo_t; // [2]
2300133 //
2300134 // [2] The structure net_ip_packet_t is not used here,
2300135 // because it refers to unfragmented packets, where
2300136 // here the max size might be less.
2300137 //
2300138 //----------------------------------------------------------
2300139 //
2300140 // Network interfaces table structure
2300141 //
2300142 typedef struct
2300143 {
2300144 unsigned int type;
2300145 h_addr_t ip; // IPv4 address in host byte order.
2300146 uint8_t m; // Short netmask.
2300147 union
2300148 {
2300149 //
2300150 // Ethernet type data:
2300151 //
2300152 struct
2300153 {
2300154 uint8_t mac[6];
2300155 uintptr_t base_io;
2300156 unsigned char irq;
2300157 net_buffer_eth_t buffer[NET_MAX_BUFFERS];
2300158 } ethernet;
2300159 //
2300160 // Loopback type data:
2300161 //
2300162 struct
2300163 {
2300164 net_buffer_lo_t buffer[NET_MAX_BUFFERS];
2300165 } loopback;
2300166 };
2300167 } net_t;
2300168 //
2300169 // [2] The structure net_ip_packet_t is not used here,
2300170 // because it refers to unfragmented packets, where
2300171 // here the max size might be less.
2300172 //
2300173 extern net_t net_table[NET_MAX_DEVICES];
2300174 //----------------------------------------------------------
2300175 int net_rx (void);
2300176 int net_tcp (void);
2300177 void net_init (void);
2300178 int net_index (h_addr_t ip);
2300179 int net_index_eth (h_addr_t ip, uint8_t mac[6],
2300180 uintptr_t io);
2300181
2300182 net_buffer_eth_t *net_buffer_eth (int n);
2300183 net_buffer_lo_t *net_buffer_lo (int n);
2300184 void net_print (void);
2300185
2300186 //void net_eth_init (int start);
2300187 int net_eth_tx (int dev, void *buffer, size_t size);
2300188 int net_eth_ip_tx (h_addr_t src, h_addr_t dst,
2300189 const void *packet, size_t size);
2300190 //----------------------------------------------------------
2300191 #endif
|
|
94.12.1
kernel/net/arp.h
Si veda la sezione 93.1.
2310001 #ifndef _KERNEL_NET_ARP_H
2310002 #define _KERNEL_NET_ARP_H 1
2310003 //----------------------------------------------------------
2310004 #include <stdint.h>
2310005 #include <sys/types.h>
2310006 #include <kernel/net/ip.h>
2310007 #include <arpa/inet.h>
2310008 //----------------------------------------------------------
2310009 #define ARP_HW_ETHERNET 1
2310010 #define ARP_HW_IEEE802 6 // Example, but not
2310011 // used.
2310012 //----------------------------------------------------------
2310013 #define ARP_TYPE_REQUEST 1
2310014 #define ARP_TYPE_REPLY 2
2310015 //----------------------------------------------------------
2310016 typedef struct
2310017 {
2310018 uint16_t hardware_type;
2310019 uint16_t protocol_type;
2310020 uint8_t hardware_address_length;
2310021 uint8_t protocol_address_length;
2310022 uint16_t opcode;
2310023 uint8_t sender_mac[NET_ETHERNET_ADDRESS_LENGTH];
2310024 uint32_t sender_ip; // Network byte order.
2310025 uint8_t target_mac[NET_ETHERNET_ADDRESS_LENGTH];
2310026 uint32_t target_ip; // Network byte order.
2310027 uint8_t filler[18]; // [1]
2310028 } __attribute__ ((packed)) arp_packet_t;
2310029 //
2310030 // [1] The filler is just big enough to get a minimal
2310031 // Ethernet frame size.
2310032 //
2310033 //----------------------------------------------------------
2310034 #define ARP_MAX_ITEMS 64
2310035 #define ARP_MAX_TIME 300 // Seconds.
2310036 //
2310037 typedef struct
2310038 {
2310039 time_t time;
2310040 uint8_t mac[NET_ETHERNET_ADDRESS_LENGTH];
2310041 h_addr_t ip; // Host byte order.
2310042 } arp_t;
2310043 //
2310044 extern arp_t arp_table[ARP_MAX_ITEMS];
2310045 //----------------------------------------------------------
2310046 void arp_clean (void);
2310047 int arp_index (unsigned char mac[6], h_addr_t ip);
2310048 void arp_init (void);
2310049 void arp_print (void);
2310050 arp_t *arp_reference (void);
2310051 void arp_request (h_addr_t ip);
2310052 int arp_rx (int n, int f);
2310053 //----------------------------------------------------------
2310054 #endif
|
|
94.12.2
kernel/net/arp/arp_clean.c
Si veda la sezione 93.1.
2320001 #include <kernel/net/arp.h>
2320002 #include <kernel/net/ip.h>
2320003 #include <kernel/lib_k.h>
2320004 #include <string.h>
2320005 //----------------------------------------------------------
2320006 void
2320007 arp_clean (void)
2320008 {
2320009 int a; // ARP table index.
2320010 //
2320011 time_t time_min = k_time (NULL) - ARP_MAX_TIME;
2320012 //
2320013 //
2320014 //
2320015 for (a = 0; a < ARP_MAX_ITEMS; a++)
2320016 {
2320017 if (arp_table[a].time < time_min)
2320018 {
2320019 //
2320020 // Too old: reset the item to all zeroes.
2320021 //
2320022 memset (&arp_table[a], 0x00,
2320023 sizeof (arp_table[a]));
2320024 }
2320025 }
2320026 }
|
|
94.12.3
kernel/net/arp/arp_index.c
Si veda la sezione 93.1.
2330001 #include <sys/os32.h>
2330002 #include <kernel/net/arp.h>
2330003 #include <kernel/driver/nic/ne2k.h>
2330004 #include <kernel/driver/pci.h>
2330005 #include <kernel/ibm_i386.h>
2330006 #include <errno.h>
2330007 //----------------------------------------------------------
2330008 extern arp_t arp_table[ARP_MAX_ITEMS];
2330009 //----------------------------------------------------------
2330010 int
2330011 arp_index (unsigned char mac[6], h_addr_t ip)
2330012 {
2330013 //
2330014 int a;
2330015 //
2330016 // By mac address.
2330017 //
2330018 if (mac != NULL)
2330019 {
2330020 for (a = 0; a < ARP_MAX_ITEMS; a++)
2330021 {
2330022 if (arp_table[a].mac[0] == mac[0]
2330023 && arp_table[a].mac[1] == mac[1]
2330024 && arp_table[a].mac[2] == mac[2]
2330025 && arp_table[a].mac[3] == mac[3]
2330026 && arp_table[a].mac[4] == mac[4]
2330027 && arp_table[a].mac[5] == mac[5])
2330028 {
2330029 return (a);
2330030 }
2330031 }
2330032 }
2330033 //
2330034 // By IPv4 address.
2330035 //
2330036 if (ip != 0)
2330037 {
2330038 for (a = 0; a < ARP_MAX_ITEMS; a++)
2330039 {
2330040 if (arp_table[a].ip == ip)
2330041 {
2330042 return (a);
2330043 }
2330044 }
2330045 }
2330046 //
2330047 // Not found!
2330048 //
2330049 errset (ENODEV);
2330050 return (-1);
2330051 }
|
|
94.12.4
kernel/net/arp/arp_init.c
Si veda la sezione 93.1.
2340001 #include <kernel/net/arp.h>
2340002 #include <string.h>
2340003 //----------------------------------------------------------
2340004 void
2340005 arp_init (void)
2340006 {
2340007 memset (arp_table, 0x00, sizeof (arp_table));
2340008 }
|
|
94.12.5
kernel/net/arp/arp_print.c
Si veda la sezione 93.1.
2350001 #include <kernel/net/arp.h>
2350002 #include <kernel/net/ip.h>
2350003 #include <kernel/lib_k.h>
2350004 //----------------------------------------------------------
2350005 void
2350006 arp_print (void)
2350007 {
2350008 int a; // ARP table index.
2350009 //
2350010 for (a = 0; a < ARP_MAX_ITEMS; a++)
2350011 {
2350012 if (arp_table[a].time > 0)
2350013 {
2350014 k_printf ("%i.%i.%i.%i ",
2350015 arp_table[a].ip >> 24 & 0x000000FF,
2350016 arp_table[a].ip >> 16 & 0x000000FF,
2350017 arp_table[a].ip >> 8 & 0x000000FF,
2350018 arp_table[a].ip >> 0 & 0x000000FF);
2350019 //
2350020 k_printf ("%02x:%02x:%02x:%02x:%02x:%02x ",
2350021 arp_table[a].mac[0],
2350022 arp_table[a].mac[1],
2350023 arp_table[a].mac[2],
2350024 arp_table[a].mac[3],
2350025 arp_table[a].mac[4],
2350026 arp_table[a].mac[5]);
2350027 //
2350028 k_printf ("%3us\n",
2350029 (unsigned int)
2350030 (k_time (NULL) - arp_table[a].time));
2350031 //
2350032 }
2350033 }
2350034 }
|
|
94.12.6
kernel/net/arp/arp_public.c
Si veda la sezione 93.1.
2360001 #include <kernel/net/arp.h>
2360002 //----------------------------------------------------------
2360003 arp_t arp_table[ARP_MAX_ITEMS];
2360004 //----------------------------------------------------------
|
|
94.12.7
kernel/net/arp/arp_reference.c
Si veda la sezione 93.1.
2370001 #include <kernel/net/arp.h>
2370002 #include <kernel/net/ip.h>
2370003 #include <sys/os32.h>
2370004 #include <kernel/lib_k.h>
2370005 //----------------------------------------------------------
2370006 #define DEBUG 0
2370007 //----------------------------------------------------------
2370008 arp_t *
2370009 arp_reference (void)
2370010 {
2370011 int a; // ARP table index.
2370012 time_t older = 0;
2370013 //
2370014 for (a = 0; a < ARP_MAX_ITEMS; a++)
2370015 {
2370016 if (arp_table[a].time == 0)
2370017 {
2370018 //
2370019 // Enough.
2370020 //
2370021 return (&arp_table[a]);
2370022 }
2370023 //
2370024 older = min (arp_table[a].time, older);
2370025 }
2370026 //
2370027 return (&arp_table[a]);
2370028 }
|
|
94.12.8
kernel/net/arp/arp_request.c
Si veda la sezione 93.1.
2380001 #include <kernel/net.h>
2380002 #include <kernel/net/arp.h>
2380003 #include <kernel/net/ip.h>
2380004 #include <sys/os32.h>
2380005 #include <kernel/lib_k.h>
2380006 #include <errno.h>
2380007 #include <arpa/inet.h>
2380008 //----------------------------------------------------------
2380009 #define DEBUG 0
2380010 //----------------------------------------------------------
2380011 void
2380012 arp_request (h_addr_t ip)
2380013 {
2380014 const uint8_t
2380015 ethernet_broadcast[NET_ETHERNET_ADDRESS_LENGTH] =
2380016 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2380017 const uint8_t
2380018 ethernet_null[NET_ETHERNET_ADDRESS_LENGTH] =
2380019 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2380020 //
2380021 net_ethernet_frame_t frame;
2380022 arp_packet_t *arp = (arp_packet_t *) & frame.packet;
2380023 int n; // NET table index.
2380024 int i;
2380025 //
2380026 // Send the ARP request to all Ethernet interfaces.
2380027 //
2380028 for (n = 0; n < NET_MAX_DEVICES; n++)
2380029 {
2380030 if (net_table[n].type & NET_DEV_ETH)
2380031 {
2380032 //
2380033 // Build the ARP request packet, starting
2380034 // from Ethernet
2380035 // MAC addresses and protocol type.
2380036 //
2380037 memcpy (frame.header.src,
2380038 net_table[n].ethernet.mac,
2380039 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2380040 memcpy (frame.header.dst, ethernet_broadcast,
2380041 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2380042 frame.header.type = htons (NET_PROT_ARP);
2380043 //
2380044 // Now the ARP packet inside.
2380045 //
2380046 arp->hardware_type = htons (ARP_HW_ETHERNET);
2380047 arp->protocol_type = htons (NET_PROT_IP);
2380048 arp->hardware_address_length
2380049 = NET_ETHERNET_ADDRESS_LENGTH;
2380050 arp->protocol_address_length
2380051 = NET_IP_ADDRESS_LENGTH;
2380052 arp->opcode = htons (ARP_TYPE_REQUEST);
2380053 memcpy (arp->sender_mac,
2380054 net_table[n].ethernet.mac,
2380055 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2380056 arp->sender_ip = htonl (net_table[n].ip);
2380057 memcpy (arp->target_mac, ethernet_null,
2380058 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2380059 //
2380060 arp->target_ip = htonl (ip);
2380061 //
2380062 for (i = 0; i < (sizeof_array (arp->filler)); i++)
2380063 {
2380064 arp->filler[i] = 0;
2380065 }
2380066 //
2380067 // Send it.
2380068 //
2380069 net_eth_tx (n, &frame,
2380070 sizeof (arp_packet_t) + 14);
2380071 }
2380072 }
2380073 }
|
|
94.12.9
kernel/net/arp/arp_rx.c
Si veda la sezione 93.1.
2390001 #include <kernel/net.h>
2390002 #include <kernel/net/arp.h>
2390003 #include <kernel/net/ip.h>
2390004 #include <sys/os32.h>
2390005 #include <kernel/lib_k.h>
2390006 #include <errno.h>
2390007 #include <arpa/inet.h>
2390008 //----------------------------------------------------------
2390009 #define DEBUG 0
2390010 //----------------------------------------------------------
2390011 int
2390012 arp_rx (int n, int f)
2390013 {
2390014 net_ethernet_frame_t *frame =
2390015 &net_table[n].ethernet.buffer[f].frame;
2390016 arp_packet_t *arp = (arp_packet_t *) & frame->packet;
2390017 int i;
2390018 int a; // ARP table index.
2390019 arp_t *arp_table_new_item;
2390020 //
2390021 net_ethernet_frame_t ans_frame;
2390022 arp_packet_t *ans_arp =
2390023 (arp_packet_t *) & ans_frame.packet;
2390024 //
2390025 //
2390026 //
2390027 if (n >= NET_MAX_DEVICES || n < 0)
2390028 {
2390029 errset (EINVAL); // Invalid argument.
2390030 return (-1);
2390031 }
2390032 //
2390033 if (!(net_table[n].type & NET_DEV_ETH))
2390034 {
2390035 errset (EINVAL); // Invalid argument.
2390036 return (-1);
2390037 }
2390038 //
2390039 if (ntohs (frame->header.type) != NET_PROT_ARP)
2390040 {
2390041 errset (EINVAL); // Invalid argument.
2390042 return (-1);
2390043 }
2390044 //
2390045 //
2390046 //
2390047 if (ntohs (arp->opcode) == ARP_TYPE_REQUEST)
2390048 {
2390049 //
2390050 // This is an ARP request: we try to answare if
2390051 // the
2390052 // the IP address is owned.
2390053 //
2390054 if (arp->target_ip == htonl (net_table[n].ip))
2390055 {
2390056 //
2390057 // Found IPv4 address. Prepare an answare.
2390058 //
2390059 memcpy (ans_frame.header.dst,
2390060 arp->sender_mac,
2390061 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2390062 memcpy (ans_frame.header.src,
2390063 net_table[n].ethernet.mac,
2390064 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2390065 ans_frame.header.type = htons (NET_PROT_ARP);
2390066 ans_arp->hardware_type = htons (ARP_HW_ETHERNET);
2390067 ans_arp->protocol_type = htons (NET_PROT_IP);
2390068 ans_arp->hardware_address_length
2390069 = NET_ETHERNET_ADDRESS_LENGTH;
2390070 ans_arp->protocol_address_length
2390071 = NET_IP_ADDRESS_LENGTH;
2390072 ans_arp->opcode = htons (ARP_TYPE_REPLY);
2390073 memcpy (ans_arp->sender_mac,
2390074 net_table[n].ethernet.mac,
2390075 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2390076 ans_arp->sender_ip = htonl (net_table[n].ip);
2390077 memcpy (ans_arp->target_mac, arp->sender_mac,
2390078 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2390079 ans_arp->target_ip = arp->sender_ip;
2390080 for (i = 0;
2390081 i < (sizeof_array (ans_arp->filler)); i++)
2390082 {
2390083 ans_arp->filler[i] = 0;
2390084 }
2390085 //
2390086 // Send it.
2390087 //
2390088 net_eth_tx (n, &ans_frame,
2390089 sizeof (arp_packet_t) + 14);
2390090 }
2390091 //
2390092 // Done.
2390093 //
2390094 return (0);
2390095 }
2390096 //
2390097 //
2390098 //
2390099 if (ntohs (arp->opcode) == ARP_TYPE_REPLY)
2390100 {
2390101 //
2390102 // We should save it inside the ARP table.
2390103 //
2390104 for (a = 0; a < ARP_MAX_ITEMS; a++)
2390105 {
2390106 //
2390107 // Check if we already have the same item.
2390108 //
2390109 if (memcmp
2390110 (arp->sender_mac, arp_table[a].mac,
2390111 (size_t) NET_ETHERNET_ADDRESS_LENGTH) == 0)
2390112 {
2390113 if (arp_table[a].ip == ntohl (arp->sender_ip))
2390114 {
2390115 //
2390116 // Found: update the time.
2390117 //
2390118 arp_table[a].time = k_time (NULL);
2390119 //
2390120 // Done.
2390121 //
2390122 return (0);
2390123 }
2390124 else
2390125 {
2390126 //
2390127 // There is already the Ethernet
2390128 // address,
2390129 // but the IP is different.
2390130 //
2390131 if (DEBUG)
2390132 {
2390133 k_printf
2390134 ("%s:%i: Ethernet address "
2390135 "%x02:%02:%x02:%x02:%02:%x02 "
2390136 "has more than one IP\n",
2390137 __FILE__, __LINE__,
2390138 arp_table[a].mac[0],
2390139 arp_table[a].mac[1],
2390140 arp_table[a].mac[2],
2390141 arp_table[a].mac[3],
2390142 arp_table[a].mac[4],
2390143 arp_table[a].mac[5]);
2390144 //
2390145 // End of scan.
2390146 //
2390147 break;
2390148 }
2390149 }
2390150 }
2390151 }
2390152 //
2390153 // If we are here, the MAC-IP couple is new: get
2390154 // a new ARP item.
2390155 //
2390156 arp_table_new_item = arp_reference ();
2390157 //
2390158 memcpy (arp_table_new_item->mac, arp->sender_mac,
2390159 (size_t) NET_ETHERNET_ADDRESS_LENGTH);
2390160 arp_table_new_item->ip = ntohl (arp->sender_ip);
2390161 arp_table_new_item->time = k_time (NULL);
2390162 //
2390163 // Done.
2390164 //
2390165 return (0);
2390166 }
2390167 //
2390168 // If we are here, we don't know the ARP type.
2390169 //
2390170 if (DEBUG)
2390171 {
2390172 k_printf ("%s:%i: unknown ARP type: %i\n",
2390173 (int) ntohs (arp->opcode));
2390174 }
2390175 //
2390176 // Done.
2390177 //
2390178 return (0);
2390179 }
|
|
94.12.10
kernel/net/icmp.h
Si veda la sezione 93.8.
2400001 #ifndef _KERNEL_NET_ICMP_H
2400002 #define _KERNEL_NET_ICMP_H 1
2400003 //----------------------------------------------------------
2400004 #include <stdint.h>
2400005 #include <sys/types.h>
2400006 #include <kernel/net/ip.h>
2400007 #include <netinet/icmp.h>
2400008 //----------------------------------------------------------
2400009 #define ICMP_HEADER_SIZE 8
2400010 #define ICMP_MAX_PACKET_SIZE NET_IP_MAX_DATA_SIZE
2400011 #define ICMP_MAX_DATA_SIZE \
2400012 ICMP_MAX_PACKET_SIZE-ICMP_HEADER_SIZE
2400013 //----------------------------------------------------------
2400014 //
2400015 // ICMP packet, for transmission.
2400016 //
2400017 typedef struct
2400018 {
2400019 struct icmphdr header;
2400020 uint8_t data[ICMP_MAX_DATA_SIZE];
2400021 } __attribute__ ((packed)) icmp_packet_t;
2400022
2400023 //----------------------------------------------------------
2400024 int icmp_rx (int i);
2400025 //
2400026 int icmp_tx (h_addr_t src, h_addr_t dst,
2400027 int type, int code, icmp_packet_t * icmp,
2400028 size_t size);
2400029 //
2400030 int icmp_tx_echo (h_addr_t src, h_addr_t dst,
2400031 int type, int code,
2400032 int identifier, int sequence,
2400033 uint8_t * data, size_t size);
2400034 //
2400035 int icmp_tx_unreachable (h_addr_t src, h_addr_t dst,
2400036 int type, int code,
2400037 uint8_t * data, size_t size);
2400038 //
2400039 //----------------------------------------------------------
2400040 #endif
|
|
94.12.11
kernel/net/icmp/icmp_rx.c
Si veda la sezione 93.8.
2410001 #include <sys/os32.h>
2410002 #include <kernel/lib_k.h>
2410003 #include <arpa/inet.h>
2410004 #include <kernel/net.h>
2410005 #include <kernel/net/ip.h>
2410006 #include <kernel/net/icmp.h>
2410007 #include <netinet/icmp.h>
2410008 #include <netinet/udp.h>
2410009 #include <kernel/lib_k.h>
2410010 #include <errno.h>
2410011 //----------------------------------------------------------
2410012 #define DEBUG 0
2410013 //----------------------------------------------------------
2410014 int
2410015 icmp_rx (int i)
2410016 {
2410017 icmp_packet_t *icmp;
2410018 size_t size;
2410019 struct iphdr *ip;
2410020 struct udphdr *ports;
2410021 h_addr_t dest = 0;
2410022 h_port_t port = 0;
2410023 int s; // Socket table index.
2410024 //
2410025 //
2410026 //
2410027 if ((i >= IP_MAX_PACKETS) || i < 0)
2410028 {
2410029 errset (EINVAL);
2410030 return (-1);
2410031 }
2410032 //
2410033 // Find the ICMP packet start, and the ICMP packet
2410034 // size (the IP
2410035 // packet size - the IP header size).
2410036 //
2410037 icmp = (icmp_packet_t *) ip_table[i].pdu4;
2410038 size = ntohs (ip_table[i].packet.header.tot_len)
2410039 - (ip_table[i].packet.header.ihl * 4);
2410040 //
2410041 // This function is used by the kernel, to do
2410042 // something automatically,
2410043 // when some ICMP packets arrive. The kernel does
2410044 // not remove the
2410045 // serviced packets, but must remember what it
2410046 // already have seen.
2410047 // If it finds that the packet clock time stamp is
2410048 // the same as
2410049 // the value saved for the kernel, there is nothing
2410050 // more to be done.
2410051 //
2410052 if (ip_table[i].kernel_serviced == ip_table[i].clock)
2410053 {
2410054 return (0);
2410055 }
2410056 //
2410057 //
2410058 //
2410059 if (icmp->header.type == ICMP_ECHO) // ECHO
2410060 // REQUEST
2410061 {
2410062 size -= sizeof (struct icmphdr);
2410063 //
2410064 // Reply: please note that source and
2410065 // destination IP addresses
2410066 // are now inverted.
2410067 //
2410068 icmp_tx_echo (ntohl
2410069 (ip_table[i].packet.header.daddr),
2410070 ntohl (ip_table[i].packet.header.saddr),
2410071 ICMP_ECHOREPLY, 0,
2410072 ntohs (icmp->header.un.echo.id),
2410073 ntohs (icmp->header.un.echo.sequence),
2410074 icmp->data, size);
2410075 //
2410076 // ICMP echo request are resolved internally,
2410077 // but the packet
2410078 // might be read from the RAW socket too. So it
2410079 // is not removed
2410080 // from the ip_table[].
2410081 //
2410082 ip_table[i].kernel_serviced = ip_table[i].clock;
2410083 }
2410084 else if (icmp->header.type == ICMP_DEST_UNREACH)
2410085 {
2410086 //
2410087 // UNREACHABLE
2410088 //
2410089 //
2410090 // The code (subtype) is not checked.
2410091 // After the ICMP header there is a copy of the
2410092 // original IP
2410093 // header.
2410094 //
2410095 ip = (struct iphdr *)
2410096 (((uint8_t *) icmp) + sizeof (struct icmphdr));
2410097 //
2410098 dest = ntohl (ip->daddr);
2410099 //
2410100 // If the IP protocol is TCP or UDP, there are
2410101 // also ports.
2410102 //
2410103 if (ip->protocol == IPPROTO_TCP
2410104 || ip->protocol == IPPROTO_UDP)
2410105 {
2410106 //
2410107 // After the IP header copy, there is the
2410108 // TCP or UDP header
2410109 // copy. To be able to get the ports, the
2410110 // UDP and TCP headers
2410111 // are the same.
2410112 //
2410113 ports =
2410114 (struct udphdr *) (((uint8_t *) ip) +
2410115 (ip->ihl * 4));
2410116 //
2410117 port = ntohs (ports->dest);
2410118 //
2410119 }
2410120 //
2410121 // Set corresponding sockets unreachable.
2410122 //
2410123 for (s = 0; s < SOCK_MAX_SLOTS; s++)
2410124 {
2410125 if (sock_table[s].active)
2410126 {
2410127 if (sock_table[s].raddr == dest)
2410128 {
2410129 if (port == 0
2410130 || port == sock_table[s].rport)
2410131 {
2410132 if (icmp->header.code ==
2410133 ICMP_NET_UNREACH)
2410134 {
2410135 sock_table[s].unreach_net = 1;
2410136 }
2410137 else if (icmp->header.code ==
2410138 ICMP_HOST_UNREACH)
2410139 {
2410140 sock_table[s].unreach_host = 1;
2410141 }
2410142 else if (icmp->header.code ==
2410143 ICMP_PROT_UNREACH)
2410144 {
2410145 sock_table[s].unreach_prot = 1;
2410146 }
2410147 else if (icmp->header.code ==
2410148 ICMP_PORT_UNREACH)
2410149 {
2410150 sock_table[s].unreach_port = 1;
2410151 }
2410152 else
2410153 {
2410154 sock_table[s].unreach_host = 1;
2410155 }
2410156 }
2410157 }
2410158 }
2410159 }
2410160 }
2410161 else if (icmp->header.type == ICMP_ECHOREPLY)
2410162 {
2410163 //
2410164 // ECHO REPLY
2410165 //
2410166 if (DEBUG)
2410167 {
2410168 k_printf ("received an echo reply\n");
2410169 }
2410170 }
2410171 else
2410172 {
2410173 //
2410174 // No other ICMP type is handled at the moment,
2410175 // but keep
2410176 // the packet, because might be read from a RAW
2410177 // ICMP socket.
2410178 //
2410179 ;
2410180 }
2410181 //
2410182 return (0);
2410183 }
|
|
94.12.12
kernel/net/icmp/icmp_tx.c
Si veda la sezione 93.8.
2420001 #include <sys/os32.h>
2420002 #include <kernel/lib_k.h>
2420003 #include <arpa/inet.h>
2420004 #include <kernel/net.h>
2420005 #include <kernel/net/ip.h>
2420006 #include <kernel/net/icmp.h>
2420007 #include <errno.h>
2420008 //----------------------------------------------------------
2420009 #define DEBUG 0
2420010 //----------------------------------------------------------
2420011 int
2420012 icmp_tx (h_addr_t src, h_addr_t dst,
2420013 int type, int code, icmp_packet_t * icmp,
2420014 size_t size)
2420015 {
2420016 uint16_t checksum;
2420017 //
2420018 // Fill the ICMP header.
2420019 //
2420020 icmp->header.type = type;
2420021 icmp->header.code = code;
2420022 icmp->header.checksum = 0;
2420023 //
2420024 // Set the header checksum.
2420025 //
2420026 checksum =
2420027 ~(ip_checksum ((void *) icmp, size, NULL, (size_t) 0));
2420028 icmp->header.checksum = htons (checksum);
2420029 //
2420030 // Send to the lower network level.
2420031 //
2420032 return (ip_tx
2420033 (src, dst, IPPROTO_ICMP, (void *) icmp, size));
2420034 }
|
|
94.12.13
kernel/net/icmp/icmp_tx_echo.c
Si veda la sezione 93.8.
2430001 #include <sys/os32.h>
2430002 #include <kernel/lib_k.h>
2430003 #include <arpa/inet.h>
2430004 #include <kernel/net.h>
2430005 #include <kernel/net/ip.h>
2430006 #include <kernel/net/icmp.h>
2430007 #include <errno.h>
2430008 //----------------------------------------------------------
2430009 #define DEBUG 0
2430010 //----------------------------------------------------------
2430011 int
2430012 icmp_tx_echo (h_addr_t src, h_addr_t dst, int type,
2430013 int code, int identifier, int sequence,
2430014 uint8_t * data, size_t size)
2430015 {
2430016 icmp_packet_t icmp;
2430017 //
2430018 // Check the data size.
2430019 //
2430020 if (size > ICMP_MAX_DATA_SIZE)
2430021 {
2430022 errset (EINVAL);
2430023 return (-1);
2430024 }
2430025 //
2430026 // Prepare the packet.
2430027 //
2430028 icmp.header.un.echo.id = htons (identifier);
2430029 icmp.header.un.echo.sequence = htons (sequence);
2430030 //
2430031 memcpy (icmp.data, data, size);
2430032 //
2430033 // Send to the lower network level.
2430034 //
2430035 return (icmp_tx
2430036 (src, dst, type, code, (void *) &icmp,
2430037 (sizeof (struct icmphdr) + size)));
2430038 }
|
|
94.12.14
kernel/net/icmp/icmp_tx_unreachable.c
Si veda la sezione 93.8.
2440001 #include <sys/os32.h>
2440002 #include <kernel/lib_k.h>
2440003 #include <arpa/inet.h>
2440004 #include <kernel/net.h>
2440005 #include <kernel/net/ip.h>
2440006 #include <kernel/net/icmp.h>
2440007 #include <errno.h>
2440008 //----------------------------------------------------------
2440009 #define DEBUG 0
2440010 //----------------------------------------------------------
2440011 int
2440012 icmp_tx_unreachable (h_addr_t src, h_addr_t dst,
2440013 int type, int code,
2440014 uint8_t * data, size_t size)
2440015 {
2440016 icmp_packet_t icmp;
2440017 //
2440018 // Check the data size and reduce if necessary.
2440019 //
2440020 size = min (size, ICMP_MAX_DATA_SIZE);
2440021 //
2440022 if (size < 8)
2440023 {
2440024 //
2440025 // The ICMP destination unreachable data must
2440026 // contain
2440027 // at least 64 bits of the original packet.
2440028 //
2440029 errset (EINVAL);
2440030 return (-1);
2440031 }
2440032 //
2440033 // Check the type: must be ICMP_DEST_UNREACH.
2440034 //
2440035 if (type != ICMP_DEST_UNREACH)
2440036 {
2440037 errset (EINVAL);
2440038 return (-1);
2440039 }
2440040 //
2440041 // Must reset the «destination unreachable»
2440042 // header.
2440043 //
2440044 memset (&icmp.header.un, 0, (size_t) 4);
2440045 //
2440046 // Copy the data inside the ICMP packet.
2440047 //
2440048 memcpy (icmp.data, data, size);
2440049 //
2440050 // Send to the lower network level.
2440051 //
2440052 return (icmp_tx
2440053 (src, dst, type, code, (void *) &icmp,
2440054 (sizeof (struct icmphdr) + size)));
2440055 }
|
|
94.12.15
kernel/net/ip.h
Si veda la sezione 93.9.
2450001 #ifndef _KERNEL_NET_IP_H
2450002 #define _KERNEL_NET_IP_H 1
2450003 //----------------------------------------------------------
2450004 #include <stdint.h>
2450005 #include <sys/types.h>
2450006 #include <kernel/net.h>
2450007 #include <netinet/ip.h>
2450008 //----------------------------------------------------------
2450009 #define IP_VERSION 4
2450010 #define IP_TTL 64
2450011 //----------------------------------------------------------
2450012 #define IP_MAX_PACKETS 64
2450013 //----------------------------------------------------------
2450014 //
2450015 // IP packet, for transmission (no options here).
2450016 // It is just the same as `ip_header_t', with the
2450017 // `data[]' member addition.
2450018 //
2450019 typedef struct
2450020 {
2450021 struct iphdr header;
2450022 uint8_t data[NET_IP_MAX_DATA_SIZE];
2450023 } __attribute__ ((packed)) ip_packet_t;
2450024 //
2450025 // IP table for IP packets.
2450026 //
2450027 typedef struct
2450028 {
2450029 clock_t clock; // [1]
2450030 clock_t kernel_serviced; // [2]
2450031 uint8_t *pdu4;
2450032 union
2450033 {
2450034 uint8_t octet[NET_IP_MAX_PACKET_SIZE];
2450035 struct iphdr header;
2450036 } packet;
2450037 } ip_t;
2450038 //
2450039 // [1] This is the arrival packet clock time stamp.
2450040 // When a new packet is to be saved inside the
2450041 // ip_table[], the older packet is replaced, even
2450042 // if it was not used. No packets are removed,
2450043 // because they might be read from a RAW socket,
2450044 // for some reason.
2450045 //
2450046 // [2] This is only for kernel usage, when a connection
2450047 // is established by the kernel, without a socket.
2450048 // The member kernel_serviced is used to remember
2450049 // to have see a certain packet and that the kernel
2450050 // does not have to try to service it again. For
2450051 // example, when an ECHO REQUEST packet arrive, the
2450052 // kernel answares with an ECHO REPLY, but does not
2450053 // remove the packet that might be read from a true
2450054 // RAW socket. So, the kernel writes inside
2450055 // kernel_serviced the same value found inside
2450056 // clock, so that it know that it was already read.
2450057 //
2450058 //
2450059 // External IP table data.
2450060 //
2450061 extern ip_t ip_table[IP_MAX_PACKETS];
2450062 //----------------------------------------------------------
2450063 uint16_t ip_checksum (uint16_t * data1, size_t size1,
2450064 uint16_t * data2, size_t size2);
2450065 int ip_rx (int n, int f);
2450066 ip_t *ip_reference (void);
2450067 ssize_t ip_header (h_addr_t src, h_addr_t dst,
2450068 uint16_t id, uint8_t ttl,
2450069 uint8_t protocol, void *buffer,
2450070 size_t length);
2450071 int ip_tx (h_addr_t src, h_addr_t dst, int protocol,
2450072 const void *buffer, size_t size);
2450073 h_addr_t ip_mask (int m);
2450074 //----------------------------------------------------------
2450075 #endif
|
|
94.12.16
kernel/net/ip/ip_checksum.c
Si veda la sezione 93.9.
2460001 #include <stdint.h>
2460002 #include <arpa/inet.h>
2460003 #include <kernel/net/ip.h>
2460004 //----------------------------------------------------------
2460005 uint16_t
2460006 ip_checksum (uint16_t * data1, size_t size1,
2460007 uint16_t * data2, size_t size2)
2460008 {
2460009 int i;
2460010 uint32_t sum;
2460011 uint16_t carry;
2460012 uint16_t checksum;
2460013 uint16_t last;
2460014 uint8_t *octet;
2460015 //
2460016 // 2's complement sum.
2460017 //
2460018 sum = 0;
2460019 //
2460020 if (data1 != NULL)
2460021 {
2460022 for (i = 0; i < (size1 / 2); i++)
2460023 {
2460024 sum += ntohs (data1[i]);
2460025 }
2460026 //
2460027 if (size1 % 2)
2460028 {
2460029 //
2460030 // The size is odd, and the last octet must
2460031 // be accounted too.
2460032 //
2460033 octet = (uint8_t *) data1;
2460034 last = octet[size1 - 1];
2460035 last = last << 8;
2460036 sum += last;
2460037 }
2460038 }
2460039 if (data2 != NULL)
2460040 {
2460041 for (i = 0; i < (size2 / 2); i++)
2460042 {
2460043 sum += ntohs (data2[i]);
2460044 }
2460045 //
2460046 if (size2 % 2)
2460047 {
2460048 //
2460049 // The size is odd, and the last octet must
2460050 // be accounted too.
2460051 //
2460052 octet = (uint8_t *) data2;
2460053 last = octet[size2 - 1];
2460054 last = last << 8;
2460055 sum += last;
2460056 }
2460057 }
2460058 //
2460059 // Extract the carries and make the checksum.
2460060 //
2460061 carry = sum >> 16;
2460062 checksum = sum & 0x0000FFFF;
2460063 checksum += carry;
2460064 //
2460065 // End of job.
2460066 //
2460067 return (checksum);
2460068 }
|
|
94.12.17
kernel/net/ip/ip_header.c
Si veda la sezione 93.9.
2470001 #include <kernel/net.h>
2470002 #include <kernel/net/ip.h>
2470003 #include <sys/os32.h>
2470004 #include <kernel/lib_k.h>
2470005 #include <errno.h>
2470006 #include <arpa/inet.h>
2470007 #include <netinet/ip.h>
2470008 //----------------------------------------------------------
2470009 #define DEBUG 0
2470010 //----------------------------------------------------------
2470011 ssize_t
2470012 ip_header (h_addr_t src, h_addr_t dst, uint16_t id,
2470013 uint8_t ttl, uint8_t protocol, void *buffer,
2470014 size_t length)
2470015 {
2470016 struct iphdr header;
2470017 uint16_t checksum;
2470018 //
2470019 // Check size.
2470020 //
2470021 if (length < sizeof (struct iphdr))
2470022 {
2470023 errset (EINVAL);
2470024 return ((ssize_t) - 1);
2470025 }
2470026 //
2470027 // Prepare the header.
2470028 //
2470029 header.version = IP_VERSION;
2470030 header.ihl = sizeof (struct iphdr) / 4;
2470031 header.tos = 0x00; // Routine, normal.
2470032 header.tot_len = htons (length);
2470033 header.id = htons (id);
2470034 header.frag_off = htons (0x4000); // Do not
2470035 // fragment!
2470036 header.ttl = ttl;
2470037 header.protocol = protocol;
2470038 header.check = 0;
2470039 header.saddr = htonl (src);
2470040 header.daddr = htonl (dst);
2470041 //
2470042 // Fix the length.
2470043 //
2470044 length = sizeof (struct iphdr);
2470045 //
2470046 // Now set the header checksum.
2470047 //
2470048 checksum = ~(ip_checksum ((void *) &header, length,
2470049 NULL, (size_t) 0));
2470050 header.check = htons (checksum);
2470051 //
2470052 // Copy the header to the buffer
2470053 //
2470054 memcpy (buffer, &header, length);
2470055 //
2470056 // Return size written.
2470057 //
2470058 return (length);
2470059 }
|
|
94.12.18
kernel/net/ip/ip_mask.c
Si veda la sezione 93.9.
2480001 #include <kernel/net.h>
2480002 #include <kernel/net/route.h>
2480003 #include <kernel/net/arp.h>
2480004 //----------------------------------------------------------
2480005 h_addr_t
2480006 ip_mask (int m)
2480007 {
2480008 int i;
2480009 uint32_t mm = 0x80000000;
2480010 h_addr_t mask = 0;
2480011 //
2480012 for (i = 0; i < m; i++)
2480013 {
2480014 mask |= mm;
2480015 mm = mm >> 1;
2480016 }
2480017 //
2480018 return mask;
2480019 }
|
|
94.12.19
kernel/net/ip/ip_public.c
Si veda la sezione 93.9.
2490001 #include <kernel/net/ip.h>
2490002 //----------------------------------------------------------
2490003 ip_t ip_table[IP_MAX_PACKETS];
2490004 //----------------------------------------------------------
|
|
94.12.20
kernel/net/ip/ip_reference.c
Si veda la sezione 93.9.
2500001 #include <kernel/net.h>
2500002 #include <kernel/net/arp.h>
2500003 #include <kernel/lib_k.h>
2500004 #include <kernel/net/ip.h>
2500005 #include <sys/os32.h>
2500006 //----------------------------------------------------------
2500007 ip_t *
2500008 ip_reference (void)
2500009 {
2500010 int i; // IP table index.
2500011 clock_t older;
2500012 int o; // Older IP table index.
2500013 //
2500014 older = ip_table[0].clock;
2500015 o = 0;
2500016 //
2500017 for (i = 0; i < IP_MAX_PACKETS; i++)
2500018 {
2500019 if (ip_table[i].clock == 0)
2500020 {
2500021 //
2500022 // Enough.
2500023 //
2500024 return (&ip_table[i]);
2500025 }
2500026 //
2500027 if (ip_table[i].clock < older)
2500028 {
2500029 older = ip_table[i].clock;
2500030 o = i;
2500031 }
2500032 }
2500033 //
2500034 return (&ip_table[o]);
2500035 }
|
|
94.12.21
kernel/net/ip/ip_rx.c
Si veda la sezione 93.9.
2510001 #include <kernel/net.h>
2510002 #include <kernel/net/arp.h>
2510003 #include <kernel/net/icmp.h>
2510004 #include <kernel/net/ip.h>
2510005 #include <sys/os32.h>
2510006 #include <kernel/lib_k.h>
2510007 #include <errno.h>
2510008 #include <arpa/inet.h>
2510009 #include <netinet/udp.h>
2510010 //----------------------------------------------------------
2510011 #define DEBUG 0
2510012 //----------------------------------------------------------
2510013 int
2510014 ip_rx (int n, int f)
2510015 {
2510016 struct iphdr *header;
2510017 net_ip_packet_t *packet;
2510018 uint16_t checksum;
2510019 size_t size_header;
2510020 ip_t *ip_table_item;
2510021 struct udphdr *udp;
2510022 int i;
2510023 int j; // Net table index.
2510024 int s; // Socket table index.
2510025 //
2510026 //
2510027 //
2510028 if (n >= NET_MAX_DEVICES || n < 0)
2510029 {
2510030 errset (EINVAL); // Invalid argument.
2510031 return (-1);
2510032 }
2510033 if (f >= NET_MAX_BUFFERS || f < 0)
2510034 {
2510035 errset (EINVAL); // Invalid argument.
2510036 return (-1);
2510037 }
2510038 //
2510039 // Get the packet link.
2510040 //
2510041 if (net_table[n].type & NET_DEV_LOOP)
2510042 {
2510043 packet = (net_ip_packet_t *)
2510044 & net_table[n].loopback.buffer[f].packet;
2510045 }
2510046 else if (net_table[n].type & NET_DEV_ETH)
2510047 {
2510048 //
2510049 // It is Ethernet, but must also have an IP
2510050 // packet inside!
2510051 //
2510052 if (ntohs
2510053 (net_table[n].ethernet.buffer[f].frame.
2510054 header.type) != NET_PROT_IP)
2510055 {
2510056 errset (EINVAL); // Invalid argument.
2510057 return (-1);
2510058 }
2510059 packet = (net_ip_packet_t *)
2510060 & net_table[n].ethernet.buffer[f].frame.packet;
2510061 }
2510062 else
2510063 {
2510064 errset (EINVAL); // Invalid argument.
2510065 return (-1);
2510066 }
2510067 //
2510068 // The beginning of the packet contains the IP
2510069 // header.
2510070 //
2510071 header = (struct iphdr *) packet;
2510072 //
2510073 // Verify IP header checksum: it is also calculated
2510074 // the real header
2510075 // size.
2510076 //
2510077 size_header = header->ihl * 4;
2510078 checksum =
2510079 ip_checksum ((uint16_t *) header, size_header,
2510080 NULL, (size_t) 0);
2510081 if (checksum == 0xFFFF || checksum == 0x0000)
2510082 {
2510083 ; // k_printf ("checksum ok\n");
2510084 }
2510085 else
2510086 {
2510087 k_printf ("BAD CHECKSUM: %04x\n", checksum);
2510088 return (0);
2510089 }
2510090 //
2510091 // Is it a fragment? As we are not able to manage
2510092 // fragments,
2510093 // we just check that it is all zero, ignoring the
2510094 // bit `DF'.
2510095 // That is why we use a mask 0xBFFF.
2510096 //
2510097 if ((ntohs (header->frag_off) & 0xBFFF) != 0)
2510098 {
2510099 //
2510100 // Sorry, we don't manage fragments.
2510101 //
2510102 k_printf
2510103 ("Sorry: we don't manage IP fragments: %04x\n",
2510104 (ntohs (header->frag_off)));
2510105 return (0);
2510106 }
2510107 else
2510108 {
2510109 //
2510110 // Find a place inside the IP table.
2510111 //
2510112 ip_table_item = ip_reference ();
2510113 //
2510114 // Copy the packet inside the ip_table[] item,
2510115 // then update
2510116 // the link to the data start inside the packet
2510117 // and the
2510118 // clock_t timestamp.
2510119 //
2510120 memcpy (ip_table_item->packet.octet, packet,
2510121 ntohs (header->tot_len));
2510122 ip_table_item->pdu4 = ip_table_item->packet.octet;
2510123 ip_table_item->pdu4 += (header->ihl * 4);
2510124 ip_table_item->clock = k_clock ();
2510125 }
2510126 //
2510127 // Check for destination unreachable, scanning the
2510128 // interface table,
2510129 // to see if there is such address here.
2510130 //
2510131 for (j = 0; j < NET_MAX_DEVICES; j++)
2510132 {
2510133 if (net_table[j].ip == ntohl (header->daddr))
2510134 {
2510135 //
2510136 // Found a valid local address.
2510137 //
2510138 break;
2510139 }
2510140 }
2510141 if (j >= NET_MAX_DEVICES)
2510142 {
2510143 //
2510144 // Local address not found: host unreachable,
2510145 // but the packet
2510146 // is taken anyway.
2510147 //
2510148 icmp_tx_unreachable (ntohl (header->daddr),
2510149 ntohl (header->saddr),
2510150 ICMP_DEST_UNREACH,
2510151 ICMP_HOST_UNREACH,
2510152 packet->octet,
2510153 ntohs (header->tot_len));
2510154 }
2510155 //
2510156 // Check for port unreachable, scanning the socket
2510157 // table.
2510158 //
2510159 if (header->protocol == IPPROTO_UDP
2510160 || header->protocol == IPPROTO_TCP)
2510161 {
2510162 //
2510163 // There are ports.
2510164 //
2510165 udp =
2510166 (struct udphdr *) &(packet->octet[header->ihl * 4]);
2510167 //
2510168 for (s = 0; s < SOCK_MAX_SLOTS; s++)
2510169 {
2510170 if (sock_table[s].active
2510171 && sock_table[s].lport == ntohs (udp->dest))
2510172 {
2510173 //
2510174 // Found a matching local port.
2510175 //
2510176 break;
2510177 }
2510178 }
2510179 if (s >= SOCK_MAX_SLOTS)
2510180 {
2510181 //
2510182 // Local port not found: port unreachable,
2510183 // but the packet
2510184 // is taken anyway.
2510185 //
2510186 icmp_tx_unreachable (ntohl (header->daddr),
2510187 ntohl (header->saddr),
2510188 ICMP_DEST_UNREACH,
2510189 ICMP_PORT_UNREACH,
2510190 packet->octet,
2510191 ntohs (header->tot_len));
2510192 }
2510193 }
2510194 //
2510195 // Now do something with the data inside the
2510196 // `ip_table[]'.
2510197 //
2510198 for (i = 0; i < IP_MAX_PACKETS; i++)
2510199 {
2510200 if (ip_table[i].clock != 0)
2510201 {
2510202 //
2510203 if (ip_table[i].kernel_serviced !=
2510204 ip_table[i].clock
2510205 && ip_table[i].packet.header.protocol ==
2510206 IPPROTO_ICMP)
2510207 {
2510208 icmp_rx (i);
2510209 }
2510210 else
2510211 {
2510212 //
2510213 // At the moment, no other IP protocol
2510214 // managed internally.
2510215 //
2510216 ip_table[i].kernel_serviced =
2510217 ip_table[i].clock;
2510218 }
2510219 }
2510220 }
2510221 //
2510222 //
2510223 //
2510224 return (0);
2510225 }
|
|
94.12.22
kernel/net/ip/ip_tx.c
Si veda la sezione 93.9.
2520001 #include <kernel/net.h>
2520002 #include <kernel/net/ip.h>
2520003 #include <kernel/net/route.h>
2520004 #include <sys/os32.h>
2520005 #include <kernel/lib_k.h>
2520006 #include <errno.h>
2520007 #include <arpa/inet.h>
2520008 //----------------------------------------------------------
2520009 #define DEBUG 0
2520010 //----------------------------------------------------------
2520011 int
2520012 ip_tx (h_addr_t src, h_addr_t dst, int protocol,
2520013 const void *buffer, size_t size)
2520014 {
2520015 static int id = 0;
2520016 ip_packet_t packet;
2520017 uint16_t checksum;
2520018 int s; // source net interface.
2520019 int d; // destination net interface.
2520020 net_buffer_lo_t *loopback;
2520021 //
2520022 // Verify to have a source address.
2520023 //
2520024 if (src == 0)
2520025 {
2520026 //
2520027 // Default source address: get the source
2520028 // address from the routing
2520029 // table, based on the destination.
2520030 //
2520031 src = route_remote_to_local (dst);
2520032 if (src == ((h_addr_t) - 1))
2520033 {
2520034 errset (errno);
2520035 return (-1);
2520036 }
2520037 }
2520038 //
2520039 // Prepare the packet.
2520040 //
2520041 packet.header.version = IP_VERSION;
2520042 packet.header.ihl = sizeof (struct iphdr) / 4;
2520043 packet.header.tos = 0x0000; // Routine, normal.
2520044 packet.header.tot_len =
2520045 htons (sizeof (struct iphdr) + size);
2520046 packet.header.id = htons (id++);
2520047 //
2520048 // Do not fragment:
2520049 //
2520050 packet.header.frag_off = htons (0x4000);
2520051 //
2520052 packet.header.ttl = IP_TTL;
2520053 packet.header.protocol = protocol;
2520054 packet.header.check = 0;
2520055 packet.header.saddr = htonl (src);
2520056 packet.header.daddr = htonl (dst);
2520057 //
2520058 // Now set the header checksum.
2520059 //
2520060 checksum =
2520061 ~(ip_checksum
2520062 ((void *) &packet, sizeof (struct iphdr), NULL,
2520063 (size_t) 0));
2520064 packet.header.check = htons (checksum);
2520065 //
2520066 memcpy (packet.data, buffer, size);
2520067 //
2520068 // //////////////////////////////////////////////////
2520069 // Enter here the lower network level.
2520070 // //////////////////////////////////////////////////
2520071 //
2520072 // The new size includes now the IPv4 header
2520073 //
2520074 size = (sizeof (struct iphdr) + size);
2520075 //
2520076 // Check for PDU size.
2520077 //
2520078 if (size > NET_MTU)
2520079 {
2520080 errset (E_PDU_TOO_BIG);
2520081 return (-1);
2520082 }
2520083 //
2520084 // Find the sender interface.
2520085 //
2520086 s = net_index (src);
2520087 if (s < 0)
2520088 {
2520089 errset (errno); // ENODEV.
2520090 return (-1);
2520091 }
2520092 //
2520093 // Check if the destination is a local interface.
2520094 //
2520095 d = net_index (dst);
2520096 if (d >= 0)
2520097 {
2520098 //
2520099 // It is a local interface, so must change the
2520100 // destination
2520101 // to the loopback device: it must be `net0'.
2520102 //
2520103 d = 0;
2520104 }
2520105 else
2520106 {
2520107 //
2520108 // Should not be necessary, but for coherence
2520109 // with the rest
2520110 // of the code...
2520111 //
2520112 d = s;
2520113 }
2520114 //
2520115 // Check if the destination is the loopback
2520116 // interface.
2520117 //
2520118 if (net_table[d].type & NET_DEV_LOOP)
2520119 {
2520120 loopback = net_buffer_lo (d);
2520121 if (loopback == NULL)
2520122 {
2520123 errset (errno);
2520124 return (-1);
2520125 }
2520126 loopback->clock = k_clock ();
2520127 loopback->size = size;
2520128 memcpy (&loopback->packet, (void *) &packet, size);
2520129 return (0);
2520130 }
2520131 //
2520132 // The destination wasn't the loopback interface, so
2520133 // check if the
2520134 // source is an Ethernet device.
2520135 //
2520136 if (net_table[s].type & NET_DEV_ETH)
2520137 {
2520138 //
2520139 // For Ethernet devices another function is
2520140 // responsible
2520141 // for sending the packet.
2520142 //
2520143 return (net_eth_ip_tx
2520144 (src, dst, (void *) &packet, size));
2520145 }
2520146 //
2520147 // Should never reach the end, but who knows...
2520148 //
2520149 errset (errno); // ENODEV.
2520150 return (-1);
2520151 }
|
|
94.12.23
kernel/net/net_buffer_eth.c
Si veda la sezione 93.17.
2530001 #include <sys/os32.h>
2530002 #include <kernel/driver/nic/ne2k.h>
2530003 #include <kernel/driver/pci.h>
2530004 #include <kernel/ibm_i386.h>
2530005 #include <errno.h>
2530006 //----------------------------------------------------------
2530007 net_buffer_eth_t *
2530008 net_buffer_eth (int n)
2530009 {
2530010 int b; // Buffer index.
2530011 int ref = -1; // Reference index.
2530012 clock_t clock = k_clock (); // Reference clock
2530013 // value.
2530014 //
2530015 // Check Ethernet index.
2530016 //
2530017 if ((n > NET_MAX_DEVICES) || (n < 0))
2530018 {
2530019 errset (EINVAL);
2530020 return (NULL);
2530021 }
2530022 //
2530023 if (!(net_table[n].type & NET_DEV_ETH))
2530024 {
2530025 errset (EINVAL);
2530026 return (NULL);
2530027 }
2530028 //
2530029 // Ethernet found.
2530030 //
2530031 for (b = 0; b < NET_MAX_BUFFERS; b++)
2530032 {
2530033 if (net_table[n].ethernet.buffer[b].clock == 0)
2530034 {
2530035 //
2530036 // Enough.
2530037 //
2530038 return &net_table[n].ethernet.buffer[b];
2530039 }
2530040 else if (net_table[n].ethernet.buffer[b].clock <
2530041 clock)
2530042 {
2530043 clock = net_table[n].ethernet.buffer[b].clock;
2530044 ref = b;
2530045 }
2530046 }
2530047 //
2530048 // Return the selected frame structure.
2530049 //
2530050 return &net_table[n].ethernet.buffer[ref];
2530051 //
2530052 // Device not found!
2530053 //
2530054 errset (ENODEV);
2530055 return (NULL);
2530056 }
|
|
94.12.24
kernel/net/net_buffer_lo.c
Si veda la sezione 93.17.
2540001 #include <sys/os32.h>
2540002 #include <kernel/net.h>
2540003 #include <kernel/driver/nic/ne2k.h>
2540004 #include <kernel/driver/pci.h>
2540005 #include <kernel/ibm_i386.h>
2540006 #include <errno.h>
2540007 //----------------------------------------------------------
2540008 net_buffer_lo_t *
2540009 net_buffer_lo (int n)
2540010 {
2540011 int b; // Buffer index.
2540012 int ref = -1; // Reference index.
2540013 clock_t clock = k_clock (); // Reference clock
2540014 // value.
2540015 //
2540016 // Check NET table index.
2540017 //
2540018 if ((n > NET_MAX_DEVICES) || (n < 0))
2540019 {
2540020 errset (EINVAL);
2540021 return (NULL);
2540022 }
2540023 //
2540024 if (!(net_table[n].type & NET_DEV_LOOP))
2540025 {
2540026 errset (EINVAL);
2540027 return (NULL);
2540028 }
2540029 //
2540030 // Loopback found.
2540031 //
2540032 for (b = 0; b < NET_MAX_BUFFERS; b++)
2540033 {
2540034 if (net_table[n].loopback.buffer[b].clock == 0)
2540035 {
2540036 //
2540037 // Enough.
2540038 //
2540039 return &net_table[n].loopback.buffer[b];
2540040 }
2540041 else if (net_table[n].loopback.buffer[b].clock <
2540042 clock)
2540043 {
2540044 clock = net_table[n].loopback.buffer[b].clock;
2540045 ref = b;
2540046 }
2540047 }
2540048 //
2540049 // Return the selected frame structure.
2540050 //
2540051 return &net_table[n].loopback.buffer[ref];
2540052 //
2540053 // Device not found!
2540054 //
2540055 errset (ENODEV);
2540056 return (NULL);
2540057 }
|
|
94.12.25
kernel/net/net_eth_ip_tx.c
Si veda la sezione 93.17.
2550001 #include <sys/os32.h>
2550002 #include <kernel/net/route.h>
2550003 #include <kernel/net/ip.h>
2550004 #include <kernel/net/arp.h>
2550005 #include <kernel/driver/nic/ne2k.h>
2550006 #include <kernel/driver/pci.h>
2550007 #include <kernel/ibm_i386.h>
2550008 #include <errno.h>
2550009 //----------------------------------------------------------
2550010 int
2550011 net_eth_ip_tx (h_addr_t src, h_addr_t dst,
2550012 const void *packet, size_t size)
2550013 {
2550014 net_ethernet_frame_t frame;
2550015 int n; // NET table index.
2550016 int a; // ARP table index.
2550017 int i;
2550018 h_addr_t router;
2550019 //
2550020 // Check for PDU size.
2550021 //
2550022 if (size > NET_ETHERNET_MAX_PACKET_SIZE)
2550023 {
2550024 errset (E_PDU_TOO_BIG);
2550025 return (-1);
2550026 }
2550027 //
2550028 // Find the sender interface address.
2550029 //
2550030 n = net_index_eth (src, NULL, (uintptr_t) 0);
2550031 if (n < 0)
2550032 {
2550033 errset (errno); // ENODEV.
2550034 return (-1);
2550035 }
2550036 //
2550037 // Copy the Ethernet source address into the
2550038 // Ethernet frame
2550039 // header.
2550040 //
2550041 memcpy (frame.header.src, net_table[n].ethernet.mac,
2550042 NET_ETHERNET_ADDRESS_LENGTH);
2550043 //
2550044 // Find if we need a router.
2550045 //
2550046 router = route_remote_to_router (dst);
2550047 //
2550048 if (router != 0 && router != ((h_addr_t) - 1))
2550049 {
2550050 //
2550051 // We need to find the router destination MAC
2550052 // address.
2550053 //
2550054 a = arp_index (NULL, router);
2550055 if (a < 0)
2550056 {
2550057 //
2550058 // There is not the item inside the ARP
2550059 // table. Send a request
2550060 // and return.
2550061 //
2550062 arp_request (router);
2550063 errset (E_ARP_MISSING);
2550064 return (-1);
2550065 }
2550066 }
2550067 else
2550068 {
2550069 //
2550070 // The destination is inside the local network.
2550071 // Find the destination Ethernet address.
2550072 //
2550073 a = arp_index (NULL, dst);
2550074 if (a < 0)
2550075 {
2550076 //
2550077 // There is not the item inside the ARP
2550078 // table. Send a request
2550079 // and return.
2550080 //
2550081 arp_request (dst);
2550082 errset (E_ARP_MISSING);
2550083 return (-1);
2550084 }
2550085 }
2550086 //
2550087 // Copy the Ethernet destination address into the
2550088 // Ethernet frame
2550089 // header: might be the real destination interface,
2550090 // or the
2550091 // router.
2550092 //
2550093 memcpy (frame.header.dst, arp_table[a].mac,
2550094 NET_ETHERNET_ADDRESS_LENGTH);
2550095 //
2550096 // Set the frame type.
2550097 //
2550098 frame.header.type = htons (NET_PROT_IP);
2550099 //
2550100 // Copy the IP packet.
2550101 //
2550102 memcpy (&frame.packet, packet, size);
2550103 //
2550104 // Fill if the size is too little.
2550105 //
2550106 for (i = size; i < NET_ETHERNET_MIN_PACKET_SIZE; i++)
2550107 {
2550108 frame.packet.octet[i] = 0;
2550109 }
2550110 //
2550111 size = max (size, NET_ETHERNET_MIN_PACKET_SIZE);
2550112 //
2550113 // Now, send the Ethernet frame. Index `n' is the
2550114 // network
2550115 // device number.
2550116 //
2550117 return (net_eth_tx
2550118 (n, &frame, size + NET_ETHERNET_HEADER_SIZE));
2550119 }
|
|
94.12.26
kernel/net/net_eth_tx.c
Si veda la sezione 93.17.
2560001 #include <sys/os32.h>
2560002 #include <kernel/net.h>
2560003 #include <kernel/driver/nic/ne2k.h>
2560004 #include <kernel/driver/pci.h>
2560005 #include <kernel/ibm_i386.h>
2560006 #include <errno.h>
2560007 //----------------------------------------------------------
2560008 int
2560009 net_eth_tx (int n, void *buffer, size_t size)
2560010 {
2560011 //
2560012 if (n >= NET_MAX_DEVICES || n < 0)
2560013 {
2560014 errset (EINVAL);
2560015 return (-1);
2560016 }
2560017 if (!(net_table[n].type & NET_DEV_ETH))
2560018 {
2560019 errset (EINVAL);
2560020 return (-1);
2560021 }
2560022 //
2560023 if (net_table[n].type == NET_DEV_ETH_NE2K)
2560024 {
2560025 return (ne2k_tx
2560026 (net_table[n].ethernet.base_io, buffer,
2560027 size));
2560028 }
2560029 //
2560030 // If we are here, there is not the driver for the
2560031 // Ethernet device.
2560032 //
2560033 errset (ENODEV);
2560034 return (-1);
2560035 }
|
|
94.12.27
kernel/net/net_index.c
Si veda la sezione 93.17.
2570001 #include <sys/os32.h>
2570002 #include <kernel/net.h>
2570003 #include <errno.h>
2570004 #include <stdint.h>
2570005 #include <arpa/inet.h>
2570006 //----------------------------------------------------------
2570007 int
2570008 net_index (h_addr_t ip)
2570009 {
2570010 //
2570011 int n;
2570012 //
2570013 // By IPv4 address.
2570014 //
2570015 if (ip != 0)
2570016 {
2570017 for (n = 0; n < NET_MAX_DEVICES; n++)
2570018 {
2570019 if (net_table[n].ip == ip)
2570020 {
2570021 return (n);
2570022 }
2570023 }
2570024 }
2570025 //
2570026 // Not found!
2570027 //
2570028 errset (ENODEV);
2570029 return (-1);
2570030 }
|
|
94.12.28
kernel/net/net_index_eth.c
Si veda la sezione 93.17.
2580001 #include <sys/os32.h>
2580002 #include <kernel/net.h>
2580003 #include <errno.h>
2580004 #include <stdint.h>
2580005 #include <arpa/inet.h>
2580006 //----------------------------------------------------------
2580007 int
2580008 net_index_eth (h_addr_t ip, uint8_t mac[6], uintptr_t io)
2580009 {
2580010 //
2580011 int n;
2580012 //
2580013 // If `ip' is not zero, then find the Ethernet table
2580014 // index by that
2580015 // value.
2580016 //
2580017 if (ip != 0)
2580018 {
2580019 for (n = 0; n < NET_MAX_DEVICES; n++)
2580020 {
2580021 if (net_table[n].type & NET_DEV_ETH)
2580022 {
2580023 if (net_table[n].ip == ip)
2580024 {
2580025 return (n);
2580026 }
2580027 }
2580028 }
2580029 }
2580030 //
2580031 // By mac address.
2580032 //
2580033 if (mac != NULL)
2580034 {
2580035 for (n = 0; n < NET_MAX_DEVICES; n++)
2580036 {
2580037 if (net_table[n].type & NET_DEV_ETH)
2580038 {
2580039 if (net_table[n].ethernet.mac[0] ==
2580040 mac[0]
2580041 && net_table[n].ethernet.mac[1] ==
2580042 mac[1]
2580043 && net_table[n].ethernet.mac[2] ==
2580044 mac[2]
2580045 && net_table[n].ethernet.mac[3] ==
2580046 mac[3]
2580047 && net_table[n].ethernet.mac[4] ==
2580048 mac[4]
2580049 && net_table[n].ethernet.mac[5] == mac[5])
2580050 {
2580051 return (n);
2580052 }
2580053 }
2580054 }
2580055 }
2580056 //
2580057 // By hardware I/O address.
2580058 //
2580059 if (io > 0)
2580060 {
2580061 for (n = 0; n < NET_MAX_DEVICES; n++)
2580062 {
2580063 if (net_table[n].type & NET_DEV_ETH)
2580064 {
2580065 if (net_table[n].ethernet.base_io == io)
2580066 {
2580067 return (n);
2580068 }
2580069 }
2580070 }
2580071 }
2580072 //
2580073 // Not found!
2580074 //
2580075 errset (ENODEV);
2580076 return (-1);
2580077 }
|
|
94.12.29
kernel/net/net_init.c
Si veda la sezione 93.17.
2590001 #include <kernel/net.h>
2590002 #include <kernel/net/route.h>
2590003 #include <kernel/net/arp.h>
2590004 #include <kernel/lib_s.h>
2590005 #include <kernel/proc.h>
2590006 #include <kernel/multiboot.h>
2590007 #include <stdlib.h>
2590008 #include <kernel/lib_k.h>
2590009 #include <string.h>
2590010 #include <errno.h>
2590011 #include <kernel/driver/pci.h>
2590012 #include <kernel/driver/nic/ne2k.h>
2590013 //----------------------------------------------------------
2590014 static void net_eth_init (int start);
2590015 //----------------------------------------------------------
2590016 void
2590017 net_init (void)
2590018 {
2590019 int n; // NET device table index.
2590020 int b; // Buffer NET device index.
2590021 int i;
2590022 char *net = "net0";
2590023 char *route = "route0";
2590024 char **argument;
2590025 in_addr_t ip_a;
2590026 in_addr_t ip_b;
2590027 int status;
2590028 //
2590029 // Reset the NET device table.
2590030 //
2590031 for (n = 0; n < NET_MAX_DEVICES; n++)
2590032 {
2590033 net_table[n].type = NET_DEV_NULL;
2590034 }
2590035 //
2590036 // Set up the loopback interface.
2590037 //
2590038 net_table[0].type = NET_DEV_LOOPBACK;
2590039 net_table[0].ip = INADDR_LOOPBACK;
2590040 net_table[0].m = 8;
2590041 //
2590042 for (b = 0; b < NET_MAX_BUFFERS; b++)
2590043 {
2590044 net_table[0].loopback.buffer[b].clock = 0;
2590045 }
2590046 //
2590047 // Prepare ARP table
2590048 //
2590049 arp_init ();
2590050 //
2590051 // Add Ethernet devices, but starting from the
2590052 // second interface
2590053 // inside the net_table[].
2590054 //
2590055 net_eth_init (1);
2590056 //
2590057 // Prepare routes.
2590058 //
2590059 route_init ();
2590060 route_sort ();
2590061 //
2590062 // Command line options: counter `i' is scanned like
2590063 // a character.
2590064 //
2590065 for (i = '0'; i <= '9'; i++)
2590066 {
2590067 net[3] = i;
2590068 argument = mboot_cmdline_opt (net, ",");
2590069 if (argument != NULL)
2590070 {
2590071 //
2590072 status = inet_pton (AF_INET, argument[2], &ip_a);
2590073 if (status != 1)
2590074 {
2590075 continue;
2590076 }
2590077 //
2590078 s_ipconfig ((pid_t) 0, atoi (argument[1]),
2590079 ip_a, atoi (argument[3]));
2590080 }
2590081 }
2590082 //
2590083 for (i = '0'; i <= '9'; i++)
2590084 {
2590085 route[5] = i;
2590086 argument = mboot_cmdline_opt (route, ",");
2590087 if (argument != NULL)
2590088 {
2590089 //
2590090 status = inet_pton (AF_INET, argument[1], &ip_a);
2590091 if (status != 1)
2590092 {
2590093 continue;
2590094 }
2590095 status = inet_pton (AF_INET, argument[3], &ip_b);
2590096 if (status != 1)
2590097 {
2590098 continue;
2590099 }
2590100 //
2590101 s_routeadd ((pid_t) 0,
2590102 ip_a, atoi (argument[2]),
2590103 ip_b, atoi (argument[4]));
2590104 }
2590105 }
2590106 //
2590107 //
2590108 //
2590109 net_print ();
2590110 route_print ();
2590111 }
2590112
2590113 //----------------------------------------------------------
2590114 static void
2590115 net_eth_init (int start)
2590116 {
2590117 int p; // PCI table index.
2590118 int n; // NET devices table index.
2590119 int i;
2590120 int j;
2590121 //
2590122 static const struct
2590123 {
2590124 unsigned short vendor;
2590125 unsigned short device;
2590126 } type_ne2k[] =
2590127 {
2590128 {
2590129 0x10ec, 0x8029}, // RealTek_RTL_8029
2590130 {
2590131 0x1050, 0x0940}, // Winbond_89C940
2590132 {
2590133 0x11f6, 0x1401}, // Compex_RL2000
2590134 {
2590135 0x8e2e, 0x3000}, // KTI_ET32P2
2590136 {
2590137 0x4a14, 0x5000}, // NetVin_NV5000SC
2590138 {
2590139 0x1106, 0x0926}, // Via_86C926
2590140 {
2590141 0x10bd, 0x0e34}, // SureCom_NE34
2590142 {
2590143 0x1050, 0x5a5a}, // Winbond_W89C940F
2590144 {
2590145 0x12c3, 0x0058}, // Holtek_HT80232
2590146 {
2590147 0x12c3, 0x5598}, // Holtek_HT80229
2590148 {
2590149 0x8c4a, 0x1980}, // Winbond_89C940_8c4a
2590150 };
2590151 //
2590152 //
2590153 //
2590154 n = start;
2590155 //
2590156 // Scan the PCI table and find NE2K Ethernet
2590157 // devices.
2590158 //
2590159 for (p = 0;
2590160 p < PCI_MAX_DEVICES && n < NET_MAX_DEVICES; p++)
2590161 {
2590162 for (i = 0; i < sizeof_array (type_ne2k); i++)
2590163 {
2590164 if (pci_table[p].vendor_id ==
2590165 type_ne2k[i].vendor
2590166 && pci_table[p].device_id ==
2590167 type_ne2k[i].device)
2590168 {
2590169 //
2590170 // Verify if the NIC is really a NE2K.
2590171 //
2590172 if (ne2k_check (pci_table[p].base_io) == 0)
2590173 {
2590174 //
2590175 // Reset the NIC and get the
2590176 // physical address.
2590177 //
2590178 if (ne2k_reset (pci_table[p].base_io,
2590179 net_table[n].
2590180 ethernet.mac) == 0)
2590181 {
2590182 //
2590183 // New.
2590184 //
2590185 net_table[n].type = NET_DEV_ETH_NE2K;
2590186 net_table[n].ethernet.base_io =
2590187 pci_table[p].base_io;
2590188 net_table[n].ethernet.irq =
2590189 pci_table[p].irq;
2590190 //
2590191 for (j = 0; j < NET_MAX_BUFFERS; j++)
2590192 {
2590193 net_table[n].ethernet.
2590194 buffer[j].clock = 0;
2590195 }
2590196 //
2590197 // Go to next NET table element.
2590198 //
2590199 n++;
2590200 //
2590201 break;
2590202 }
2590203 }
2590204 }
2590205 }
2590206 }
2590207 }
|
|
94.12.30
kernel/net/net_print.c
Si veda la sezione 93.17.
2600001 #include <sys/os32.h>
2600002 #include <kernel/net.h>
2600003 #include <errno.h>
2600004 //----------------------------------------------------------
2600005 void
2600006 net_print (void)
2600007 {
2600008 int n; // NET devices table index.
2600009 char string[80];
2600010 //
2600011 //
2600012 //
2600013 k_printf ("dev "
2600014 "address/mask "
2600015 "mac " "io irq\n");
2600016 //
2600017 for (n = 0; n < NET_MAX_DEVICES; n++)
2600018 {
2600019 if (net_table[n].type != NET_DEV_NULL)
2600020 {
2600021 sprintf (string, "net%i ", n);
2600022 string[6] = '\0';
2600023 k_printf ("%s", string);
2600024 //
2600025 sprintf (string, "%i.%i.%i.%i/%i "
2600026 " ",
2600027 net_table[n].ip >> 24 & 0x000000FF,
2600028 net_table[n].ip >> 16 & 0x000000FF,
2600029 net_table[n].ip >> 8 & 0x000000FF,
2600030 net_table[n].ip >> 0 & 0x000000FF,
2600031 net_table[n].m);
2600032 string[20] = '\0';
2600033 k_printf ("%s", string);
2600034 //
2600035 if (net_table[n].type & NET_DEV_ETH)
2600036 {
2600037 k_printf
2600038 ("%02x:%02x:%02x:%02x:%02x:%02x "
2600039 "0x%04x %i",
2600040 net_table[n].ethernet.mac[0],
2600041 net_table[n].ethernet.mac[1],
2600042 net_table[n].ethernet.mac[2],
2600043 net_table[n].ethernet.mac[3],
2600044 net_table[n].ethernet.mac[4],
2600045 net_table[n].ethernet.mac[5],
2600046 net_table[n].ethernet.base_io,
2600047 net_table[n].ethernet.irq);
2600048 }
2600049 k_printf ("\n");
2600050 }
2600051 }
2600052 }
|
|
94.12.31
kernel/net/net_public.c
Si veda la sezione 93.17.
2610001 #include <kernel/net.h>
2610002 //----------------------------------------------------------
2610003 net_t net_table[NET_MAX_DEVICES];
2610004 //----------------------------------------------------------
|
|
94.12.32
kernel/net/net_rx.c
Si veda la sezione 93.17.
2620001 #include <arpa/inet.h>
2620002 #include <kernel/net.h>
2620003 #include <kernel/net/arp.h>
2620004 #include <sys/os32.h>
2620005 #include <kernel/lib_k.h>
2620006 //----------------------------------------------------------
2620007 #define DEBUG 0
2620008 //----------------------------------------------------------
2620009 int
2620010 net_rx (void)
2620011 {
2620012 int n; // NET table index.
2620013 int b; // Frame index.
2620014 net_ethernet_frame_t *frame;
2620015 int counter = 0;
2620016 //
2620017 // Scan NET table.
2620018 //
2620019 for (n = 0; n < NET_MAX_DEVICES; n++)
2620020 {
2620021 //
2620022 // Ethernet.
2620023 //
2620024 if (net_table[n].type & NET_DEV_ETH)
2620025 {
2620026 for (b = 0; b < NET_MAX_BUFFERS; b++)
2620027 {
2620028 if (net_table[n].ethernet.buffer[b].clock > 0)
2620029 {
2620030 frame = (net_ethernet_frame_t *)
2620031 & net_table[n].ethernet.buffer[b].frame;
2620032 //
2620033 if (ntohs (frame->header.type) ==
2620034 NET_PROT_ARP)
2620035 {
2620036 arp_rx (n, b);
2620037 //
2620038 // Remove packet from buffer.
2620039 //
2620040 net_table[n].ethernet.buffer[b].
2620041 clock = 0;
2620042 //
2620043 // Increment the packet received
2620044 // counter.
2620045 //
2620046 counter++;
2620047 }
2620048 else if (ntohs (frame->header.type)
2620049 == NET_PROT_IP)
2620050 {
2620051 ip_rx (n, b);
2620052 //
2620053 // Remove packet from buffer.
2620054 //
2620055 net_table[n].ethernet.buffer[b].
2620056 clock = 0;
2620057 //
2620058 // Increment the packet received
2620059 // counter.
2620060 //
2620061 counter++;
2620062 }
2620063 else
2620064 {
2620065 //
2620066 // Unknown frame type.
2620067 //
2620068 k_printf
2620069 ("received an unknown frame "
2620070 "type %04x\n",
2620071 ntohs (frame->header.type));
2620072 //
2620073 // Remove packet from buffer.
2620074 //
2620075 net_table[n].ethernet.buffer[b].
2620076 clock = 0;
2620077 //
2620078 // Increment the packet received
2620079 // counter anyway.
2620080 //
2620081 counter++;
2620082 }
2620083 }
2620084 }
2620085 }
2620086 //
2620087 // Loopback
2620088 //
2620089 else if (net_table[n].type & NET_DEV_LOOP)
2620090 {
2620091 for (b = 0; b < NET_MAX_BUFFERS; b++)
2620092 {
2620093 if (net_table[n].loopback.buffer[b].clock > 0)
2620094 {
2620095 ip_rx (n, b);
2620096 //
2620097 // Remove packet from buffer.
2620098 //
2620099 net_table[n].loopback.buffer[b].clock = 0;
2620100 //
2620101 // Increment the packet received
2620102 // counter.
2620103 //
2620104 counter++;
2620105 //
2620106 }
2620107 }
2620108 }
2620109 }
2620110 //
2620111 // Remove ARP items that are too old.
2620112 //
2620113 arp_clean ();
2620114 //
2620115 //
2620116 //
2620117 return (counter);
2620118 }
|
|
94.12.33
kernel/net/route.h
Si veda la sezione 93.21.
2630001 #ifndef _KERNEL_NET_ROUTE_H
2630002 #define _KERNEL_NET_ROUTE_H 1
2630003 //----------------------------------------------------------
2630004 #include <stdint.h>
2630005 #include <sys/types.h>
2630006 #include <kernel/net.h>
2630007 #include <netinet/in.h>
2630008 //----------------------------------------------------------
2630009 #define ROUTE_MAX_ROUTES 16
2630010 //
2630011 // Route table element.
2630012 //
2630013 typedef struct
2630014 {
2630015 h_addr_t network; // 32 bit, host byte order.
2630016 h_addr_t netmask; // 32 bit, host byte order.
2630017 h_addr_t router; // 32 bit, host byte order.
2630018 uint8_t m; // Short netmask.
2630019 uint8_t interface;
2630020 } route_t;
2630021 //
2630022 // External routing table data.
2630023 //
2630024 extern route_t route_table[ROUTE_MAX_ROUTES];
2630025 //----------------------------------------------------------
2630026 void route_init (void);
2630027 void route_sort (void);
2630028 void route_print (void);
2630029 h_addr_t route_remote_to_local (h_addr_t remote);
2630030 h_addr_t route_remote_to_router (h_addr_t remote);
2630031
2630032 //----------------------------------------------------------
2630033 #endif
|
|
94.12.34
kernel/net/route/route_init.c
Si veda la sezione 93.21.
2640001 #include <arpa/inet.h>
2640002 #include <sys/os32.h>
2640003 #include <kernel/net/route.h>
2640004 #include <errno.h>
2640005 #include <netinet/in.h>
2640006 //----------------------------------------------------------
2640007 void
2640008 route_init (void)
2640009 {
2640010 //
2640011 // Reset the table with 0xFF.
2640012 //
2640013 memset (route_table, 0xFF, sizeof (route_table));
2640014 //
2640015 // Put the loopback routing.
2640016 //
2640017 route_table[0].netmask = 0xFF000000; // Little
2640018 // endian.
2640019 route_table[0].m = 8;
2640020 route_table[0].network =
2640021 INADDR_LOOPBACK & route_table[0].netmask;
2640022 route_table[0].router = 0;
2640023 route_table[0].interface = 0;
2640024 }
|
|
94.12.35
kernel/net/route/route_print.c
Si veda la sezione 93.21.
2650001 #include <arpa/inet.h>
2650002 #include <sys/os32.h>
2650003 #include <kernel/net/route.h>
2650004 #include <kernel/lib_k.h>
2650005 #include <errno.h>
2650006 //----------------------------------------------------------
2650007 void
2650008 route_print (void)
2650009 {
2650010 int r; // Routing table index.
2650011 char string[80];
2650012 //
2650013 k_printf ("Destination/mask "
2650014 "Router " "Interface\n");
2650015 //
2650016 for (r = 0; r < ROUTE_MAX_ROUTES; r++)
2650017 {
2650018 if (route_table[r].network == 0xFFFFFFFF)
2650019 {
2650020 //
2650021 // Empty item.
2650022 //
2650023 continue;
2650024 }
2650025 //
2650026 sprintf (string, "%i.%i.%i.%i/%i"
2650027 " ",
2650028 route_table[r].network >> 24 & 0x000000FF,
2650029 route_table[r].network >> 16 & 0x000000FF,
2650030 route_table[r].network >> 8 & 0x000000FF,
2650031 route_table[r].network >> 0 & 0x000000FF,
2650032 route_table[r].m);
2650033 string[19] = '\0';
2650034 k_printf ("%s", string);
2650035 //
2650036 if (route_table[r].router == 0)
2650037 {
2650038 k_printf (" ");
2650039 }
2650040 else
2650041 {
2650042 sprintf (string, "%i.%i.%i.%i"
2650043 " ",
2650044 route_table[r].router >> 24 & 0x000000FF,
2650045 route_table[r].router >> 16 & 0x000000FF,
2650046 route_table[r].router >> 8 & 0x000000FF,
2650047 route_table[r].router >> 0 & 0x000000FF);
2650048 string[16] = '\0';
2650049 k_printf ("%s", string);
2650050 }
2650051 //
2650052 k_printf ("net%i\n", route_table[r].interface);
2650053 }
2650054 }
|
|
94.12.36
kernel/net/route/route_public.c
Si veda la sezione 93.21.
2660001 #include <kernel/net/route.h>
2660002 //----------------------------------------------------------
2660003 route_t route_table[ROUTE_MAX_ROUTES];
2660004 //----------------------------------------------------------
|
|
94.12.37
kernel/net/route/route_remote_to_local.c
Si veda la sezione 93.21.
2670001 #include <arpa/inet.h>
2670002 #include <sys/os32.h>
2670003 #include <kernel/net/route.h>
2670004 #include <kernel/lib_k.h>
2670005 #include <errno.h>
2670006 //----------------------------------------------------------
2670007 h_addr_t
2670008 route_remote_to_local (h_addr_t remote)
2670009 {
2670010 int r; // Routing table index.
2670011 int d; // Network interface number.
2670012 h_addr_t network;
2670013 //
2670014 for (r = 0; r < ROUTE_MAX_ROUTES; r++)
2670015 {
2670016 //
2670017 // Calculate the remote network address based on
2670018 // the current
2670019 // router item netmask.
2670020 //
2670021 network = remote & route_table[r].netmask;
2670022 //
2670023 // Compare the calculated network address with
2670024 // the remote
2670025 // network.
2670026 //
2670027 if (route_table[r].network == network)
2670028 {
2670029 //
2670030 // Found.
2670031 //
2670032 d = route_table[r].interface;
2670033 //
2670034 // Check inside the network interfaces.
2670035 //
2670036 if (net_table[d].ip == 0)
2670037 {
2670038 errset (ENODEV);
2670039 return ((h_addr_t) - 1);
2670040 }
2670041 else
2670042 {
2670043 return (net_table[d].ip);
2670044 }
2670045 }
2670046 }
2670047 //
2670048 // Sorry: destination not found.
2670049 //
2670050 errset (EADDRNOTAVAIL);
2670051 return ((h_addr_t) - 1);
2670052 }
|
|
94.12.38
kernel/net/route/route_remote_to_router.c
Si veda la sezione 93.21.
2680001 #include <arpa/inet.h>
2680002 #include <sys/os32.h>
2680003 #include <kernel/net/route.h>
2680004 #include <kernel/lib_k.h>
2680005 #include <errno.h>
2680006 //----------------------------------------------------------
2680007 h_addr_t
2680008 route_remote_to_router (h_addr_t remote)
2680009 {
2680010 int r; // Routing table index.
2680011 h_addr_t network;
2680012 //
2680013 for (r = 0; r < ROUTE_MAX_ROUTES; r++)
2680014 {
2680015 //
2680016 // Calculate the remote network address based on
2680017 // the current
2680018 // router item netmask.
2680019 //
2680020 network = remote & route_table[r].netmask;
2680021 //
2680022 // Compare the calculated network address with
2680023 // the remote
2680024 // network: routes are sorted, from the most
2680025 // detailed to the
2680026 // less one.
2680027 //
2680028 if (route_table[r].network == network)
2680029 {
2680030 //
2680031 // Found.
2680032 //
2680033 return (route_table[r].router);
2680034 }
2680035 }
2680036 //
2680037 // Sorry: destination not found.
2680038 //
2680039 errset (EADDRNOTAVAIL);
2680040 return ((h_addr_t) - 1);
2680041 }
|
|
94.12.39
kernel/net/route/route_sort.c
Si veda la sezione 93.21.
2690001 #include <sys/os32.h>
2690002 #include <kernel/net/route.h>
2690003 #include <errno.h>
2690004 //----------------------------------------------------------
2690005 static int part (char *array, size_t size, int a,
2690006 int z, int (*compare) (void *, void *));
2690007 static void sort (char *array, size_t size, int a,
2690008 int z, int (*compare) (void *, void *));
2690009 static void qsort (void *base, size_t nmemb,
2690010 size_t size, int (*compare) (void *,
2690011 void *));
2690012 //
2690013 static uint8_t swap[sizeof (route_t)];
2690014 static int comp (void *a, void *b);
2690015 //----------------------------------------------------------
2690016 void
2690017 route_sort (void)
2690018 {
2690019 qsort (route_table, ROUTE_MAX_ROUTES,
2690020 sizeof (route_t), comp);
2690021 }
2690022
2690023 //----------------------------------------------------------
2690024 static int
2690025 comp (void *a, void *b)
2690026 {
2690027 route_t *route_a = a;
2690028 route_t *route_b = b;
2690029 uint8_t m_a = route_a->m;
2690030 uint8_t m_b = route_b->m;
2690031 //
2690032 if (m_a > m_b)
2690033 return (-1);
2690034 if (m_a < m_b)
2690035 return (1);
2690036 return (0);
2690037 }
2690038
2690039 //----------------------------------------------------------
2690040 static void
2690041 qsort (void *base, size_t nmemb, size_t size,
2690042 int (*compare) (void *, void *))
2690043 {
2690044 if (size <= 1)
2690045 {
2690046 //
2690047 // There is nothing to sort!
2690048 //
2690049 return;
2690050 }
2690051 else
2690052 {
2690053 sort ((char *) base, size, 0, (int) (nmemb - 1),
2690054 compare);
2690055 }
2690056 }
2690057
2690058 //----------------------------------------------------------
2690059 static void
2690060 sort (char *array, size_t size, int a, int z,
2690061 int (*compare) (void *, void *))
2690062 {
2690063 int loc;
2690064 //
2690065 if (z > a)
2690066 {
2690067 loc = part (array, size, a, z, compare);
2690068 if (loc >= 0)
2690069 {
2690070 sort (array, size, a, loc - 1, compare);
2690071 sort (array, size, loc + 1, z, compare);
2690072 }
2690073 }
2690074 }
2690075
2690076 //----------------------------------------------------------
2690077 static int
2690078 part (char *array, size_t size, int a, int z,
2690079 int (*compare) (void *, void *))
2690080 {
2690081 int i;
2690082 int loc;
2690083 //
2690084 if (z <= a)
2690085 {
2690086 errset (EUNKNOWN); // Should never
2690087 // happen.
2690088 return (-1);
2690089 }
2690090 //
2690091 // Index `i' after the first element; index `loc' at
2690092 // the last
2690093 // position.
2690094 //
2690095 i = a + 1;
2690096 loc = z;
2690097 //
2690098 // Loop as long as index `loc' is higher than index
2690099 // `i'.
2690100 // When index `loc' is less or equal to index `i',
2690101 // then, index `loc' is the right position for the
2690102 // first element of the current piece of array.
2690103 //
2690104 for (;;)
2690105 {
2690106 //
2690107 // Index `i' goes up...
2690108 //
2690109 for (; i < loc; i++)
2690110 {
2690111 if (compare
2690112 (&array[i * size], &array[a * size]) > 0)
2690113 {
2690114 break;
2690115 }
2690116 }
2690117 //
2690118 // Index `loc' gose down...
2690119 //
2690120 for (;; loc--)
2690121 {
2690122 if (compare
2690123 (&array[loc * size], &array[a * size]) <= 0)
2690124 {
2690125 break;
2690126 }
2690127 }
2690128 //
2690129 // Swap elements related to index `i' and `loc'.
2690130 //
2690131 if (loc <= i)
2690132 {
2690133 //
2690134 // The array is completely scanned.
2690135 //
2690136 break;
2690137 }
2690138 else
2690139 {
2690140 memcpy (swap, &array[loc * size], size);
2690141 memcpy (&array[loc * size], &array[i * size],
2690142 size);
2690143 memcpy (&array[i * size], swap, size);
2690144 }
2690145 }
2690146 //
2690147 // Swap the first element with the one related to
2690148 // the
2690149 // index `loc'.
2690150 //
2690151 memcpy (swap, &array[loc * size], size);
2690152 memcpy (&array[loc * size], &array[a * size], size);
2690153 memcpy (&array[a * size], swap, size);
2690154 //
2690155 // Return the index `loc'.
2690156 //
2690157 return (loc);
2690158 }
|
|
94.12.40
kernel/net/tcp.h
Si veda la sezione 93.23.
2700001 #ifndef _KERNEL_NET_TCP_H
2700002 #define _KERNEL_NET_TCP_H 1
2700003 //----------------------------------------------------------
2700004 #include <netinet/tcp.h>
2700005 #include <kernel/net.h>
2700006 //----------------------------------------------------------
2700007 #define TCP_HEADER_SIZE 20
2700008 #define TCP_MAX_PACKET_SIZE NET_IP_MAX_DATA_SIZE
2700009 #define TCP_MAX_DATA_SIZE \
2700010 TCP_MAX_PACKET_SIZE-TCP_HEADER_SIZE
2700011 //
2700012 #define TCP_MAX_DELAY (CLOCKS_PER_SEC*2)
2700013 //----------------------------------------------------------
2700014 //
2700015 // TCP packet, for transmission.
2700016 //
2700017 typedef struct
2700018 {
2700019 struct tcphdr header;
2700020 uint8_t data[TCP_MAX_DATA_SIZE];
2700021 } __attribute__ ((packed)) tcp_packet_t;
2700022 //
2700023 // TCP pseudo header for checksum calculation.
2700024 //
2700025 typedef struct
2700026 {
2700027 in_addr_t saddr;
2700028 in_addr_t daddr;
2700029 uint8_t zero;
2700030 uint8_t protocol;
2700031 uint16_t length;
2700032 } __attribute__ ((packed)) tcp_pseudo_header_t;
2700033 //----------------------------------------------------------
2700034 #define TCP_FLAG_NULL 0
2700035 #define TCP_FLAG_ACK 1
2700036 #define TCP_FLAG_PSH 2
2700037 #define TCP_FLAG_RST 4
2700038 #define TCP_FLAG_SYN 8
2700039 #define TCP_FLAG_FIN 16
2700040 //----------------------------------------------------------
2700041 #define TCP_TRY_READ 1 // 2^0 Wake up reading
2700042 // TCP process.
2700043 #define TCP_TRY_WRITE 2 // 2^1 Wake up writing
2700044 // TCP process.
2700045 //----------------------------------------------------------
2700046 int tcp_tx_raw (h_port_t sport, h_port_t dport,
2700047 uint32_t seq, uint32_t ack_seq,
2700048 int flags,
2700049 h_addr_t saddr, h_addr_t daddr,
2700050 const void *buffer, size_t size);
2700051 int tcp_tx_sock (void *sock_item);
2700052 int tcp_tx_ack (void *sock_item);
2700053 int tcp_rx_ack (void *sock_item, void *packet);
2700054 int tcp (void);
2700055 int tcp_connect (void *sock_item);
2700056 int tcp_tx_rst (void *ip_packet);
2700057 void tcp_test (void);
2700058 void tcp_show (h_addr_t src, h_addr_t dst,
2700059 const struct tcphdr *tcphdr);
2700060 int tcp_close (void *sock_item);
2700061 int tcp_rx_data (void *sock_item, void *packet);
2700062 int tcp_status (void *ip_packet);
2700063 //----------------------------------------------------------
2700064 #endif
|
|
94.12.41
kernel/net/tcp/tcp.c
Si veda la sezione 93.23.
2710001 #include <stdlib.h>
2710002 #include <string.h>
2710003 #include <netinet/ip.h>
2710004 #include <netinet/tcp.h>
2710005 #include <kernel/net.h>
2710006 #include <kernel/net/tcp.h>
2710007 #include <kernel/fs.h>
2710008 #include <kernel/lib_s.h>
2710009 #include <kernel/lib_k.h>
2710010 #include <errno.h>
2710011 //----------------------------------------------------------
2710012 #define DEBUG 0
2710013 //----------------------------------------------------------
2710014 int
2710015 tcp (void)
2710016 {
2710017 int s; // Socket table index.
2710018 int p; // IP table index.
2710019 int q; // Queue index.
2710020 int status;
2710021 struct tcphdr *tcp;
2710022 struct iphdr *ip;
2710023 int sfdn; // New socket.
2710024 fd_t *sfd;
2710025 sock_t *sock;
2710026 struct sockaddr_in sa;
2710027 clock_t delay;
2710028 uint8_t *recv_data;
2710029 size_t recv_size;
2710030 int ret = 0;
2710031 unsigned int lseq;
2710032 //
2710033 // Scan local sockets.
2710034 //
2710035 for (s = 0; s < SOCK_MAX_SLOTS; s++)
2710036 {
2710037 if (!sock_table[s].active)
2710038 continue;
2710039 if (sock_table[s].family != AF_INET)
2710040 continue;
2710041 if (sock_table[s].protocol != IPPROTO_TCP)
2710042 continue;
2710043 if (sock_table[s].unreach_port)
2710044 continue;
2710045 if (sock_table[s].unreach_host)
2710046 continue;
2710047 //
2710048 // Calculate the delay from the last send.
2710049 //
2710050 delay = s_clock ((pid_t) 0) - sock_table[s].tcp.clock;
2710051 //
2710052 // Have we received something? Scan the
2710053 // ip_table[] to find a
2710054 // TCP packet that was not already seen by the
2710055 // socket.
2710056 //
2710057 for (p = 0; p < IP_MAX_PACKETS; p++)
2710058 {
2710059 // //////////////////////////////////////////
2710060 // PACKET CHECK
2710061 // //////////////////////////////////////////
2710062 //
2710063 // Check the protocol.
2710064 //
2710065 if (ip_table[p].packet.header.protocol !=
2710066 IPPROTO_TCP)
2710067 {
2710068 //
2710069 // It is not TCP.
2710070 //
2710071 continue;
2710072 }
2710073 //
2710074 // Is the packet new for the socket?
2710075 //
2710076 if (ip_table[p].clock <=
2710077 sock_table[s].read.clock[p])
2710078 {
2710079 //
2710080 // Already seen or packet too old.
2710081 //
2710082 continue;
2710083 }
2710084 //
2710085 // Get a pointer to IP and TCP headers.
2710086 //
2710087 ip = (struct iphdr *) &ip_table[p].packet.header;
2710088 tcp =
2710089 (struct tcphdr *) &ip_table[p].packet.
2710090 octet[ip->ihl * 4];
2710091 //
2710092 // Verify the ports.
2710093 //
2710094 if (tcp->dest != htons (sock_table[s].lport))
2710095 {
2710096 //
2710097 // The local port does not match!
2710098 //
2710099 continue;
2710100 }
2710101 //
2710102 if (tcp->source != htons (sock_table[s].rport))
2710103 {
2710104 //
2710105 // The remote port does not match, but
2710106 // might be
2710107 // listening and the packet might be a
2710108 // SYN.
2710109 //
2710110 if (sock_table[s].rport == 0
2710111 && sock_table[s].tcp.conn ==
2710112 TCP_LISTEN && tcp->syn && !tcp->ack)
2710113 {
2710114 //
2710115 // We hope that it is the first SYN.
2710116 //
2710117 ;
2710118 }
2710119 else
2710120 {
2710121 continue;
2710122 }
2710123 }
2710124 //
2710125 // Verify the IP addresses.
2710126 //
2710127 if (ip_table[p].packet.header.daddr
2710128 != htonl (sock_table[s].laddr))
2710129 {
2710130 //
2710131 // The local address does not match, but
2710132 // might be zero.
2710133 //
2710134 if (sock_table[s].laddr != 0)
2710135 {
2710136 //
2710137 // The local address is not zero, so
2710138 // the match fails.
2710139 //
2710140 continue;
2710141 }
2710142 }
2710143 //
2710144 if (ip_table[p].packet.header.saddr
2710145 != htonl (sock_table[s].raddr))
2710146 {
2710147 //
2710148 // The remote address does not match,
2710149 // but the socket
2710150 // might be listening and che packet
2710151 // might be a SYN.
2710152 //
2710153 if (sock_table[s].raddr == 0
2710154 && sock_table[s].tcp.conn ==
2710155 TCP_LISTEN && tcp->syn && !tcp->ack)
2710156 {
2710157 //
2710158 // We hope that it is the first SYN.
2710159 //
2710160 ;
2710161 }
2710162 else
2710163 {
2710164 continue;
2710165 }
2710166 }
2710167 //
2710168 // This TCP packet is new for the socket:
2710169 // save the clock time, so that the
2710170 // same packet is not read again.
2710171 //
2710172 sock_table[s].read.clock[p] = ip_table[p].clock;
2710173 //
2710174 // //////////////////////////////////////////
2710175 // TCP PROTOCOL
2710176 // //////////////////////////////////////////
2710177 //
2710178 if (DEBUG)
2710179 {
2710180 tcp_show (ntohl (ip->saddr),
2710181 ntohl (ip->daddr), tcp);
2710182 }
2710183 //
2710184 recv_data = &((uint8_t *) tcp)[tcp->doff * 4];
2710185 recv_size =
2710186 ntohs (ip->tot_len) - (ip->ihl * 4) -
2710187 (tcp->doff * 4);
2710188 //
2710189 // Now we have received a TCP packet for the
2710190 // current
2710191 // socket, and we should do something with
2710192 // it...
2710193 //
2710194 if (tcp->rst)
2710195 {
2710196 //
2710197 // We have received a reset... What is
2710198 // resetting?
2710199 //
2710200 if ((sock_table[s].tcp.
2710201 rsq[sock_table[s].tcp.rsqi] ==
2710202 ntohl (tcp->seq)) || (tcp->ack
2710203 &&
2710204 (sock_table[s].tcp.
2710205 lsq_ack ==
2710206 ntohl (tcp->
2710207 ack_seq))))
2710208 {
2710209 sock_table[s].tcp.recv_closed = 1;
2710210 sock_table[s].tcp.send_closed = 1;
2710211 sock_table[s].tcp.conn = TCP_RESET;
2710212 if (DEBUG)
2710213 {
2710214 k_printf ("[%s] TCP_RESET\n",
2710215 __func__);
2710216 }
2710217 }
2710218 else
2710219 {
2710220 k_printf ("lsq_ack=%3, rsq=%3\n",
2710221 sock_table[s].tcp.lsq_ack,
2710222 sock_table[s].tcp.
2710223 rsq[sock_table[s].tcp.rsqi]);
2710224 }
2710225 }
2710226 else if (sock_table[s].tcp.conn == 0
2710227 || sock_table[s].tcp.conn ==
2710228 TCP_CLOSE
2710229 || sock_table[s].tcp.conn == TCP_RESET)
2710230 {
2710231 //
2710232 // The connection is not yet ready or it
2710233 // is closed.
2710234 // We are not waiting any packet, so we
2710235 // just reject it.
2710236 //
2710237 tcp_tx_rst (ip);
2710238 }
2710239 else if (sock_table[s].tcp.conn == TCP_LISTEN)
2710240 {
2710241 //
2710242 // It should be a first SYN packet.
2710243 //
2710244 if (tcp->syn && !tcp->ack)
2710245 {
2710246 //
2710247 // Should be a new connection
2710248 // attempt. Can we queue
2710249 // it?
2710250 //
2710251 for (q = 0;
2710252 q <
2710253 sock_table[s].tcp.listen_max; q++)
2710254 {
2710255 if (sock_table[s].tcp.
2710256 listen_queue[q] == -1)
2710257 {
2710258 break;
2710259 }
2710260 }
2710261 if (q >= sock_table[s].tcp.listen_max)
2710262 {
2710263 //
2710264 // The queue is full.
2710265 //
2710266 tcp_tx_rst (ip);
2710267 //
2710268 // Next packet.
2710269 //
2710270 continue;
2710271 }
2710272 //
2710273 // Is this connection attempt
2710274 // already done?
2710275 //
2710276 status = tcp_status (ip);
2710277 //
2710278 if (status < 0)
2710279 {
2710280 //
2710281 // Should not happen.
2710282 //
2710283 errset (errno);
2710284 perror (NULL);
2710285 //
2710286 // Ignore the packet?!
2710287 //
2710288 continue;
2710289 }
2710290 else if (status == TCP_SYN_SENT)
2710291 {
2710292 //
2710293 // The same SYN was already
2710294 // received and serviced:
2710295 // just ignore the packet.
2710296 //
2710297 continue;
2710298 }
2710299 else if (status > 0)
2710300 {
2710301 //
2710302 // There is already a connection
2710303 // with the same
2710304 // addresses: ignore the SYN.
2710305 //
2710306 continue;
2710307 }
2710308 //
2710309 // The SYN is new!
2710310 // Can we open a new socket?
2710311 //
2710312 sfdn =
2710313 s_socket (sock_table[s].tcp.listen_pid,
2710314 AF_INET, SOCK_STREAM,
2710315 IPPROTO_TCP);
2710316 if (sfdn < 0)
2710317 {
2710318 //
2710319 // No, sorry.
2710320 //
2710321 tcp_tx_rst (ip);
2710322 //
2710323 // Next packet.
2710324 //
2710325 continue;
2710326 }
2710327 //
2710328 // Can we bind it to the same
2710329 // destination of the
2710330 // received packet?
2710331 //
2710332 sa.sin_family = AF_INET;
2710333 sa.sin_port = tcp->dest;
2710334 sa.sin_addr.s_addr = ip->daddr;
2710335 status =
2710336 s_bind (sock_table[s].tcp.listen_pid,
2710337 sfdn, (struct sockaddr *) &sa,
2710338 sizeof (sa));
2710339 if (status < 0)
2710340 {
2710341 //
2710342 // No, sorry.
2710343 //
2710344 tcp_tx_rst (ip);
2710345 close (sfdn);
2710346 //
2710347 // Next packet.
2710348 //
2710349 continue;
2710350 }
2710351 //
2710352 // Ok. Save the new socket number in
2710353 // queue.
2710354 //
2710355 sock_table[s].tcp.listen_queue[q] = sfdn;
2710356 //
2710357 // Prepare some pointers to reach
2710358 // the new socket
2710359 // easily.
2710360 //
2710361 sfd =
2710362 fd_reference (sock_table[s].tcp.
2710363 listen_pid, &sfdn);
2710364 sock = sfd->file->sock;
2710365 //
2710366 // Connect the new socket with the
2710367 // remote node.
2710368 //
2710369 sock->raddr = ntohl (ip->saddr);
2710370 sock->rport = ntohs (tcp->source);
2710371 //
2710372 // The new socket has seen this SYN
2710373 // packet.
2710374 //
2710375 sock->read.clock[p] = ip_table[p].clock;
2710376 //
2710377 // Make the new socket answare with
2710378 // a second
2710379 // SYN.
2710380 //
2710381 memset (sock->tcp.lsq, 0x00,
2710382 sizeof (sock->tcp.lsq));
2710383 memset (sock->tcp.rsq, 0x00,
2710384 sizeof (sock->tcp.rsq));
2710385 srand ((unsigned int)
2710386 s_clock ((pid_t) 0));
2710387 lseq = rand ();
2710388 sock->tcp.lsq_ack = lseq + 1;
2710389 sock->tcp.lsq[++sock->tcp.lsqi] = lseq;
2710390 sock->tcp.rsq[++sock->tcp.rsqi] =
2710391 ntohl (tcp->seq);
2710392 sock->tcp.rsq[++sock->tcp.rsqi] =
2710393 ntohl (tcp->seq) + 1;
2710394 //
2710395 sock->tcp.can_send = 1;
2710396 sock->tcp.send_flags =
2710397 TCP_FLAG_SYN | TCP_FLAG_ACK;
2710398 if (DEBUG)
2710399 {
2710400 k_printf
2710401 ("[%s] New conn. seq=%3u, "
2710402 "lsq_ack=%3u\n",
2710403 __func__, lseq, sock->tcp.lsq_ack);
2710404 }
2710405 tcp_tx_sock (sock);
2710406 //
2710407 // Put the new socket to
2710408 // TCP_SYN_RECV status.
2710409 //
2710410 sock->tcp.conn = TCP_SYN_RECV;
2710411 }
2710412 else
2710413 {
2710414 //
2710415 // We are listening: cannot accept
2710416 // other type of
2710417 // packets.
2710418 //
2710419 tcp_tx_rst (ip);
2710420 }
2710421 }
2710422 else if (sock_table[s].tcp.conn == TCP_SYN_SENT)
2710423 {
2710424 //
2710425 // It should be a second SYN packet with
2710426 // ACK.
2710427 //
2710428 if (tcp->syn
2710429 && tcp->ack
2710430 && tcp_rx_ack (&sock_table[s], ip) == 0)
2710431 {
2710432 //
2710433 // SYN + ACK.
2710434 //
2710435 // Save the initial remote sequence,
2710436 // because it
2710437 // is the first one, and save also
2710438 // the remote
2710439 // sequence that we will expect next
2710440 // time.
2710441 //
2710442 sock_table[s].tcp.rsq[++sock_table[s].
2710443 tcp.rsqi] =
2710444 ntohl (tcp->seq);
2710445 sock_table[s].tcp.rsq[++sock_table[s].
2710446 tcp.rsqi] =
2710447 ntohl (tcp->seq) + 1;
2710448 //
2710449 // The received SYN is to be
2710450 // confirmed with ACK.
2710451 // The expected next local sequence
2710452 // does not change,
2710453 // and in effect, we don't expect
2710454 // any other ACK back.
2710455 //
2710456 sock_table[s].tcp.lsq[++sock_table[s].
2710457 tcp.lsqi] =
2710458 sock_table[s].tcp.lsq_ack;
2710459 tcp_tx_ack (&sock_table[s]);
2710460 //
2710461 // We are now in TCP_ESTABLISHED.
2710462 //
2710463 sock_table[s].tcp.conn = TCP_ESTABLISHED;
2710464 //
2710465 // Now the process can write and can
2710466 // receive
2710467 // data (can write --but cannot
2710468 // send-- and can
2710469 // receive --but cannot read--).
2710470 //
2710471 sock_table[s].tcp.can_write = 1;
2710472 sock_table[s].tcp.can_send = 0;
2710473 //
2710474 sock_table[s].tcp.can_recv = 1;
2710475 sock_table[s].tcp.can_read = 0;
2710476 //
2710477 ret |= TCP_TRY_WRITE;
2710478 }
2710479 //
2710480 // The case of a single ACK and a single
2710481 // SYN is not
2710482 // taken into consideration!
2710483 //
2710484 // No other type of packet is expected
2710485 // here.
2710486 //
2710487 }
2710488 else if (sock_table[s].tcp.conn == TCP_SYN_RECV)
2710489 {
2710490 //
2710491 // We are waiting an ACK for our second
2710492 // SYN.
2710493 //
2710494 if (tcp->ack
2710495 && tcp_rx_ack (&sock_table[s], ip) == 0)
2710496 {
2710497 //
2710498 // ACK ok.
2710499 // The connection is ready.
2710500 //
2710501 sock_table[s].tcp.conn = TCP_ESTABLISHED;
2710502 //
2710503 // Now the process can write and can
2710504 // receive
2710505 // data (can write --but cannot
2710506 // send-- and can
2710507 // receive --but cannot read--).
2710508 //
2710509 sock_table[s].tcp.can_write = 1;
2710510 sock_table[s].tcp.can_send = 0;
2710511 //
2710512 sock_table[s].tcp.can_recv = 1;
2710513 sock_table[s].tcp.can_read = 0;
2710514 //
2710515 ret |= TCP_TRY_WRITE;
2710516 }
2710517 //
2710518 // No other type of packet is expected
2710519 // here.
2710520 //
2710521 }
2710522 else if (sock_table[s].tcp.conn ==
2710523 TCP_ESTABLISHED)
2710524 {
2710525 //
2710526 // Might be a repeated SYN + ACK,
2710527 // because the other
2710528 // side don't have received our ACK.
2710529 // Just resend.
2710530 //
2710531 if (tcp->syn && tcp->ack)
2710532 {
2710533 tcp_tx_ack (&sock_table[s]);
2710534 //
2710535 // Next packet.
2710536 //
2710537 continue;
2710538 }
2710539 //
2710540 // It might be a normal ACK.
2710541 //
2710542 if (tcp->ack)
2710543 {
2710544 //
2710545 // Verify if the packet contains
2710546 // data: if there is
2710547 // data, before sending the ACK,
2710548 // must verify to be
2710549 // able to receive such data.
2710550 //
2710551 if (recv_size > 0)
2710552 {
2710553 // k_printf ("[%i]", (int)
2710554 // recv_size);
2710555 //
2710556 // There is data.
2710557 //
2710558 if (!sock_table[s].tcp.can_recv)
2710559 {
2710560 //
2710561 // At the moment, cannot
2710562 // receive: the packet
2710563 // is currently ignored and
2710564 // no ACK is sent.
2710565 //
2710566 continue;
2710567 }
2710568 }
2710569 //
2710570 // The received packet is empty or
2710571 // it can be received.
2710572 //
2710573 if (tcp_rx_ack (&sock_table[s], ip) == 0)
2710574 {
2710575 //
2710576 // ACK ok.
2710577 // The process can continue to
2710578 // write and the packet
2710579 // don't have to be resent.
2710580 //
2710581 sock_table[s].tcp.can_write = 1;
2710582 sock_table[s].tcp.can_send = 0;
2710583 //
2710584 ret |= TCP_TRY_WRITE;
2710585 }
2710586 else
2710587 {
2710588 //
2710589 // Next packet.
2710590 //
2710591 continue;
2710592 }
2710593 }
2710594 //
2710595 // It might be a FIN.
2710596 //
2710597 if (tcp->fin)
2710598 {
2710599 //
2710600 // Is the FIN in the right sequence?
2710601 //
2710602 if (sock_table[s].tcp.
2710603 rsq[sock_table[s].tcp.rsqi] ==
2710604 ntohl (tcp->seq))
2710605 {
2710606 //
2710607 // Yes, it is: close receiving.
2710608 //
2710609 sock_table[s].tcp.recv_closed = 1;
2710610 //
2710611 // ACK.
2710612 //
2710613 sock_table[s].tcp.
2710614 rsq[++sock_table[s].tcp.rsqi] =
2710615 ntohl (tcp->seq) + 1;
2710616 sock_table[s].tcp.
2710617 lsq[++sock_table[s].tcp.lsqi] =
2710618 sock_table[s].tcp.lsq_ack;
2710619 tcp_tx_ack (&sock_table[s]);
2710620 //
2710621 // Change status.
2710622 //
2710623 if (DEBUG)
2710624 {
2710625 k_printf
2710626 ("[%s] TCP_CLOSE_WAIT\n",
2710627 __func__);
2710628 }
2710629 sock_table[s].tcp.conn =
2710630 TCP_CLOSE_WAIT;
2710631 }
2710632 else
2710633 {
2710634 //
2710635 // Just ignore it and jump to
2710636 // the next packet.
2710637 //
2710638 continue;
2710639 }
2710640 }
2710641 //
2710642 // The received packet might contain
2710643 // some data, but can
2710644 // accept data only if the receiving
2710645 // buffer is empty
2710646 // (was already read from the reading
2710647 // process).
2710648 //
2710649 tcp_rx_data (&sock_table[s], ip);
2710650 //
2710651 ret |= TCP_TRY_READ;
2710652 }
2710653 else if (sock_table[s].tcp.conn == TCP_CLOSE_WAIT)
2710654 {
2710655 //
2710656 // It might be an ACK.
2710657 //
2710658 if (tcp->ack)
2710659 {
2710660 if (tcp_rx_ack (&sock_table[s], ip) == 0)
2710661 {
2710662 //
2710663 // ACK ok.
2710664 // The process can continue to
2710665 // write and the packet
2710666 // don't have to be resent.
2710667 //
2710668 sock_table[s].tcp.can_write = 1;
2710669 sock_table[s].tcp.can_send = 0;
2710670 //
2710671 ret |= TCP_TRY_WRITE;
2710672 }
2710673 else
2710674 {
2710675 //
2710676 // Next packet.
2710677 //
2710678 continue;
2710679 }
2710680 }
2710681 //
2710682 // The data coming from the outside is
2710683 // not taken anymore.
2710684 //
2710685 }
2710686 else if (sock_table[s].tcp.conn == TCP_LAST_ACK)
2710687 {
2710688 //
2710689 // It might be the final ACK.
2710690 //
2710691 if (tcp->ack)
2710692 {
2710693 if (tcp_rx_ack (&sock_table[s], ip) == 0)
2710694 {
2710695 //
2710696 // ACK ok. The two directions
2710697 // are closed and
2710698 // the packet confirmed don't
2710699 // have to be resent.
2710700 //
2710701 sock_table[s].tcp.recv_closed = 1;
2710702 sock_table[s].tcp.send_closed = 1;
2710703 sock_table[s].tcp.can_send = 0;
2710704 //
2710705 // Change status.
2710706 //
2710707 if (DEBUG)
2710708 {
2710709 k_printf ("[%s] TCP_CLOSE\n",
2710710 __func__);
2710711 }
2710712 sock_table[s].tcp.conn = TCP_CLOSE;
2710713 }
2710714 else
2710715 {
2710716 //
2710717 // Next packet.
2710718 //
2710719 continue;
2710720 }
2710721 }
2710722 //
2710723 // The data coming from the outside is
2710724 // not taken anymore.
2710725 //
2710726 }
2710727 else if (sock_table[s].tcp.conn == TCP_FIN_WAIT1)
2710728 {
2710729 if (tcp->ack && tcp->fin)
2710730 {
2710731 //
2710732 // ACK and FIN
2710733 //
2710734 if (tcp_rx_ack (&sock_table[s], ip) == 0)
2710735 {
2710736 //
2710737 // ACK ok: the confirmed packet
2710738 // don't have to
2710739 // be resent.
2710740 //
2710741 sock_table[s].tcp.conn =
2710742 TCP_FIN_WAIT2;
2710743 sock_table[s].tcp.can_send = 0;
2710744 }
2710745 else
2710746 {
2710747 //
2710748 // Next packet.
2710749 //
2710750 continue;
2710751 }
2710752 //
2710753 // Is the FIN in the right sequence?
2710754 //
2710755 if (sock_table[s].tcp.
2710756 rsq[sock_table[s].tcp.rsqi] ==
2710757 ntohl (tcp->seq))
2710758 {
2710759 //
2710760 // Yes, it is: close receiving.
2710761 //
2710762 sock_table[s].tcp.recv_closed = 1;
2710763 //
2710764 // ACK.
2710765 //
2710766 sock_table[s].tcp.
2710767 rsq[++sock_table[s].tcp.rsqi] =
2710768 ntohl (tcp->seq) + 1;
2710769 sock_table[s].tcp.
2710770 lsq[++sock_table[s].tcp.lsqi] =
2710771 sock_table[s].tcp.lsq_ack;
2710772 tcp_tx_ack (&sock_table[s]);
2710773 //
2710774 // Change status.
2710775 //
2710776 if (DEBUG)
2710777 {
2710778 k_printf
2710779 ("[%s] TCP_TIME_WAIT\n",
2710780 __func__);
2710781 }
2710782 sock_table[s].tcp.conn =
2710783 TCP_TIME_WAIT;
2710784 }
2710785 else
2710786 {
2710787 //
2710788 // Just ignore it and jump to
2710789 // the next packet.
2710790 //
2710791 continue;
2710792 }
2710793 }
2710794 else if (tcp->ack)
2710795 {
2710796 //
2710797 // ACK only.
2710798 //
2710799 if (tcp_rx_ack (&sock_table[s], ip) == 0)
2710800 {
2710801 //
2710802 // ACK ok: the confirmed packet
2710803 // don't have to
2710804 // be resent.
2710805 //
2710806 sock_table[s].tcp.conn =
2710807 TCP_FIN_WAIT2;
2710808 sock_table[s].tcp.can_send = 0;
2710809 }
2710810 else
2710811 {
2710812 //
2710813 // Next packet.
2710814 //
2710815 continue;
2710816 }
2710817 }
2710818 //
2710819 // The received packet might contain
2710820 // some data, but can
2710821 // accept data only if the receive
2710822 // channel is open and
2710823 // if the receiving buffer is empty.
2710824 //
2710825 tcp_rx_data (&sock_table[s], ip);
2710826 //
2710827 ret |= TCP_TRY_READ;
2710828 }
2710829 else if (sock_table[s].tcp.conn == TCP_FIN_WAIT2)
2710830 {
2710831 //
2710832 // It might be the final ACK.
2710833 //
2710834 if (tcp->fin && tcp->ack)
2710835 {
2710836 if (tcp_rx_ack (&sock_table[s], ip) == 0)
2710837 {
2710838 //
2710839 // ACK ok: the packet don't have
2710840 // to be resent.
2710841 //
2710842 sock_table[s].tcp.conn =
2710843 TCP_TIME_WAIT;
2710844 sock_table[s].tcp.can_send = 0;
2710845 //
2710846 // Next packet.
2710847 //
2710848 continue;
2710849 }
2710850 else
2710851 {
2710852 //
2710853 // Next packet.
2710854 //
2710855 continue;
2710856 }
2710857 }
2710858 //
2710859 // The received packet might contain
2710860 // some data, but can
2710861 // accept data only if the receiving
2710862 // buffer is empty
2710863 // (was already read from the reading
2710864 // process).
2710865 //
2710866 tcp_rx_data (&sock_table[s], ip);
2710867 //
2710868 ret |= TCP_TRY_READ;
2710869 }
2710870 else if (sock_table[s].tcp.conn == TCP_TIME_WAIT)
2710871 {
2710872 //
2710873 // It might be duplicate final ACK.
2710874 //
2710875 if (tcp->fin && tcp->ack)
2710876 {
2710877 //
2710878 // Just resend the ACK.
2710879 //
2710880 tcp_tx_ack (&sock_table[s]);
2710881 }
2710882 //
2710883 // Close receiving too, if it is not
2710884 // already done.
2710885 //
2710886 sock_table[s].tcp.recv_closed = 1;
2710887 //
2710888 // Change status, without waiting
2710889 // anymore.
2710890 //
2710891 if (DEBUG)
2710892 {
2710893 k_printf ("[%s] TCP_CLOSE\n", __func__);
2710894 }
2710895 sock_table[s].tcp.conn = TCP_CLOSE;
2710896 }
2710897 }
2710898 //
2710899 // See if there is something to be re-sent (if
2710900 // the flag
2710901 // `tcp.can_send' is set).
2710902 //
2710903 if (sock_table[s].tcp.can_send
2710904 && delay > TCP_MAX_DELAY)
2710905 {
2710906 tcp_tx_sock (&sock_table[s]);
2710907 }
2710908 }
2710909 //
2710910 // Return.
2710911 //
2710912 return (ret);
2710913 }
|
|
94.12.42
kernel/net/tcp/tcp_close.c
Si veda la sezione 93.23.
2720001 #include <stdlib.h>
2720002 #include <netinet/ip.h>
2720003 #include <netinet/tcp.h>
2720004 #include <errno.h>
2720005 #include <kernel/net.h>
2720006 #include <kernel/net/tcp.h>
2720007 #include <kernel/fs.h>
2720008 #include <kernel/lib_k.h>
2720009 //----------------------------------------------------------
2720010 #define DEBUG 0
2720011 //----------------------------------------------------------
2720012 int
2720013 tcp_close (void *sock_item)
2720014 {
2720015 sock_t *sock = sock_item;
2720016 //
2720017 // Is there already a connection?
2720018 //
2720019 if (sock->tcp.conn == 0 || sock->tcp.conn == TCP_CLOSE)
2720020 {
2720021 //
2720022 // Done or never opened.
2720023 //
2720024 return (0);
2720025 }
2720026 else if (sock->tcp.conn == TCP_RESET)
2720027 {
2720028 //
2720029 // Change to closed.
2720030 //
2720031 if (DEBUG)
2720032 {
2720033 k_printf ("[%s] TCP_CLOSE\n", __func__);
2720034 }
2720035 sock->tcp.conn = TCP_CLOSE;
2720036 return (0);
2720037 }
2720038 else if (sock->tcp.conn == TCP_TIME_WAIT)
2720039 {
2720040 //
2720041 // Assume that the time is elapsed.
2720042 //
2720043 sock->tcp.conn = TCP_CLOSE;
2720044 if (DEBUG)
2720045 {
2720046 k_printf ("[%s] TCP_CLOSE\n", __func__);
2720047 }
2720048 sock->tcp.conn = TCP_CLOSE;
2720049 return (0);
2720050 }
2720051 else if (sock->tcp.conn == TCP_FIN_WAIT1)
2720052 {
2720053 errset (EALREADY);
2720054 return (-1);
2720055 }
2720056 else if (sock->tcp.conn == TCP_FIN_WAIT2)
2720057 {
2720058 errset (EALREADY);
2720059 return (-1);
2720060 }
2720061 else if (sock->tcp.conn == TCP_ESTABLISHED)
2720062 {
2720063 sock->tcp.can_send = 1;
2720064 sock->tcp.lsq[++sock->tcp.lsqi] = sock->tcp.lsq_ack;
2720065 sock->tcp.send_flags = TCP_FLAG_FIN | TCP_FLAG_ACK;
2720066 tcp_tx_sock (sock);
2720067 sock->tcp.conn = TCP_FIN_WAIT1;
2720068 if (DEBUG)
2720069 k_printf ("[%s] TCP_FIN_WAIT1\n", __func__);
2720070 errset (EINPROGRESS);
2720071 return (-1);
2720072 }
2720073 else if (sock->tcp.conn == TCP_CLOSE_WAIT)
2720074 {
2720075 sock->tcp.can_send = 1;
2720076 sock->tcp.lsq[++sock->tcp.lsqi] = sock->tcp.lsq_ack;
2720077 sock->tcp.send_flags = TCP_FLAG_FIN | TCP_FLAG_ACK;
2720078 tcp_tx_sock (sock);
2720079 sock->tcp.conn = TCP_LAST_ACK;
2720080 if (DEBUG)
2720081 k_printf ("[%s] TCP_LAST_ACK\n", __func__);
2720082 errset (EINPROGRESS);
2720083 return (-1);
2720084 }
2720085 else
2720086 {
2720087 sock->tcp.can_send = 1;
2720088 sock->tcp.lsq[++sock->tcp.lsqi] = sock->tcp.lsq_ack;
2720089 sock->tcp.send_flags = TCP_FLAG_FIN | TCP_FLAG_ACK;
2720090 tcp_tx_sock (sock);
2720091 sock->tcp.conn = TCP_CLOSE;
2720092 if (DEBUG)
2720093 k_printf ("[%s] TCP_CLOSE\n", __func__);
2720094 return (0);
2720095 }
2720096 }
|
|
94.12.43
kernel/net/tcp/tcp_connect.c
Si veda la sezione 93.23.
2730001 #include <stdlib.h>
2730002 #include <netinet/ip.h>
2730003 #include <netinet/tcp.h>
2730004 #include <errno.h>
2730005 #include <kernel/net.h>
2730006 #include <kernel/net/tcp.h>
2730007 #include <kernel/fs.h>
2730008 #include <kernel/lib_k.h>
2730009 //----------------------------------------------------------
2730010 #define DEBUG 0
2730011 //----------------------------------------------------------
2730012 int
2730013 tcp_connect (void *sock_item)
2730014 {
2730015 sock_t *sock = sock_item;
2730016 unsigned int lseq;
2730017 //
2730018 // Is there already a connection?
2730019 //
2730020 if (sock->tcp.conn == 0 || sock->tcp.conn == TCP_CLOSE)
2730021 {
2730022 //
2730023 // There isn't.
2730024 //
2730025 memset (sock->tcp.lsq, 0x00, sizeof (sock->tcp.lsq));
2730026 memset (sock->tcp.rsq, 0x00, sizeof (sock->tcp.rsq));
2730027 srand ((unsigned int) s_clock ((pid_t) 0));
2730028 lseq = rand ();
2730029 sock->tcp.lsq_ack = lseq + 1;
2730030 sock->tcp.lsq[++sock->tcp.lsqi] = lseq;
2730031 //
2730032 sock->tcp.can_send = 1;
2730033 sock->tcp.send_size = 0;
2730034 sock->tcp.send_flags = TCP_FLAG_SYN;
2730035 tcp_tx_sock (sock);
2730036 //
2730037 sock->tcp.conn = TCP_SYN_SENT;
2730038 //
2730039 // The operation has begun and will take some
2730040 // time.
2730041 //
2730042 errset (EINPROGRESS);
2730043 return (-1);
2730044 }
2730045 else if (sock->tcp.conn == TCP_RESET)
2730046 {
2730047 //
2730048 // Cannot connect: the socket status is reset to
2730049 // closed, to let
2730050 // the process retry, if it is really willing to
2730051 // do it.
2730052 //
2730053 sock->tcp.conn = TCP_CLOSE;
2730054 errset (ECONNREFUSED);
2730055 return (-1);
2730056 }
2730057 else if (sock->tcp.conn == TCP_SYN_SENT
2730058 || sock->tcp.conn == TCP_SYN_RECV)
2730059 {
2730060 //
2730061 // Already in progress.
2730062 //
2730063 errset (EALREADY);
2730064 return (-1);
2730065 }
2730066 else if (sock->tcp.conn == TCP_ESTABLISHED)
2730067 {
2730068 //
2730069 // Connection established.
2730070 //
2730071 return (0);
2730072 }
2730073 else
2730074 {
2730075 //
2730076 // Cannot reconnect.
2730077 //
2730078 errset (EISCONN);
2730079 return (-1);
2730080 }
2730081 }
|
|
94.12.44
kernel/net/tcp/tcp_rx_ack.c
Si veda la sezione 93.23.
2740001 #include <kernel/net.h>
2740002 #include <kernel/net/ip.h>
2740003 #include <kernel/net/route.h>
2740004 #include <kernel/net/tcp.h>
2740005 #include <sys/os32.h>
2740006 #include <kernel/lib_k.h>
2740007 #include <kernel/fs.h>
2740008 #include <errno.h>
2740009 #include <arpa/inet.h>
2740010 #include <netinet/in.h>
2740011 #include <netinet/tcp.h>
2740012 //----------------------------------------------------------
2740013 #define DEBUG 0
2740014 //----------------------------------------------------------
2740015 int
2740016 tcp_rx_ack (void *sock_item, void *packet)
2740017 {
2740018 sock_t *sock = sock_item;
2740019 struct iphdr *iphdr = packet;
2740020 struct tcphdr *tcphdr = (struct tcphdr *)
2740021 &((uint8_t *) packet)[iphdr->ihl * 4];
2740022 int i;
2740023 //
2740024 // Is the ACK sequence right?
2740025 //
2740026 if (sock->tcp.lsq_ack != ntohl (tcphdr->ack_seq))
2740027 {
2740028 //
2740029 // If it is a previous sequence, just ignore
2740030 // the packet.
2740031 //
2740032 for (i = 0; i < 16; i++)
2740033 {
2740034 if (sock->tcp.lsq[i] == ntohl (tcphdr->ack_seq))
2740035 {
2740036 break;
2740037 }
2740038 }
2740039 if (i >= 16)
2740040 {
2740041 if (DEBUG)
2740042 {
2740043 k_printf ("ERR loc seq: ");
2740044 tcp_show (ntohl (iphdr->saddr),
2740045 ntohl (iphdr->daddr), tcphdr);
2740046
2740047 int j;
2740048 for (j = 0; j < 16; j++)
2740049 {
2740050 if (sock->tcp.lsq[j] != 0)
2740051 {
2740052 k_printf ("%3u ", sock->tcp.lsq[j]);
2740053 }
2740054 }
2740055 k_printf ("lsq_ack=%3u ", sock->tcp.lsq_ack);
2740056 k_printf ("\n");
2740057 }
2740058 //
2740059 // The ACK is out of sequence: sorry.
2740060 //
2740061 tcp_tx_rst (iphdr);
2740062 }
2740063 return (-1);
2740064 }
2740065 //
2740066 // Is the TCP sequence what we expected? But notice
2740067 // that, if our
2740068 // remote expected sequence is zero, this is the
2740069 // first time that
2740070 // get it, so it is right.
2740071 //
2740072 if (sock->tcp.rsq[sock->tcp.rsqi] != 0
2740073 && sock->tcp.rsq[sock->tcp.rsqi] !=
2740074 ntohl (tcphdr->seq))
2740075 {
2740076 //
2740077 // If it is a previous sequence, just ignore
2740078 // the packet.
2740079 //
2740080 for (i = 0; i < 16; i++)
2740081 {
2740082 if (sock->tcp.rsq[i] == ntohl (tcphdr->seq))
2740083 {
2740084 break;
2740085 }
2740086 }
2740087 if (i >= 16)
2740088 {
2740089 //
2740090 // The packet is out of sequence: sorry.
2740091 //
2740092 if (DEBUG)
2740093 {
2740094 k_printf ("ERR rem seq: ");
2740095 tcp_show (ntohl (iphdr->saddr),
2740096 ntohl (iphdr->daddr), tcphdr);
2740097
2740098 int j;
2740099 for (j = 0; j < 16; j++)
2740100 {
2740101 if (sock->tcp.rsq[j] != 0)
2740102 {
2740103 k_printf ("%3u ", sock->tcp.rsq[j]);
2740104 }
2740105 }
2740106 k_printf ("\n");
2740107 }
2740108 tcp_tx_rst (iphdr);
2740109 }
2740110 return (-1);
2740111 }
2740112 return (0);
2740113 }
|
|
94.12.45
kernel/net/tcp/tcp_rx_data.c
Si veda la sezione 93.23.
2750001 #include <kernel/net.h>
2750002 #include <kernel/net/ip.h>
2750003 #include <kernel/net/route.h>
2750004 #include <kernel/net/tcp.h>
2750005 #include <sys/os32.h>
2750006 #include <kernel/lib_k.h>
2750007 #include <kernel/fs.h>
2750008 #include <errno.h>
2750009 #include <arpa/inet.h>
2750010 #include <netinet/in.h>
2750011 #include <netinet/tcp.h>
2750012 //----------------------------------------------------------
2750013 #define DEBUG 0
2750014 //----------------------------------------------------------
2750015 int
2750016 tcp_rx_data (void *sock_item, void *packet)
2750017 {
2750018 sock_t *sock = sock_item;
2750019 struct iphdr *iphdr = packet;
2750020 struct tcphdr *tcphdr = (struct tcphdr *)
2750021 &((uint8_t *) packet)[iphdr->ihl * 4];
2750022 uint8_t *recv_data;
2750023 size_t recv_size;
2750024 //
2750025 recv_data = &((uint8_t *) tcphdr)[tcphdr->doff * 4];
2750026 recv_size = ntohs (iphdr->tot_len) - (iphdr->ihl * 4)
2750027 - (tcphdr->doff * 4);
2750028 //
2750029 if (DEBUG)
2750030 {
2750031 if (recv_size > 0 && !sock->tcp.can_recv)
2750032 {
2750033 k_printf ("[%s] not ready to get data\n",
2750034 __func__);
2750035 }
2750036 }
2750037 //
2750038 // If we receive zero data, it is ok.
2750039 //
2750040 if (recv_size == 0)
2750041 {
2750042 //
2750043 // Nothing to do, but there is no error.
2750044 //
2750045 return (0);
2750046 }
2750047 if (recv_size < 0)
2750048 {
2750049 return (-1);
2750050 }
2750051 if (recv_size > 0 && !sock->tcp.can_recv)
2750052 {
2750053 return (-1);
2750054 }
2750055 //
2750056 // Check the size.
2750057 //
2750058 if (recv_size > sizeof (sock->tcp.recv_data))
2750059 {
2750060 k_printf ("[%s] cannot accept a packet "
2750061 "payload of %u bytes; packet "
2750062 "truncated at %u bytes!\n",
2750063 __func__, recv_size,
2750064 sizeof (sock->tcp.recv_data));
2750065 //
2750066 recv_size = sizeof (sock->tcp.recv_data);
2750067 }
2750068 //
2750069 memcpy (sock->tcp.recv_data, recv_data, recv_size);
2750070 sock->tcp.recv_size = recv_size;
2750071 sock->tcp.recv_index = sock->tcp.recv_data;
2750072 //
2750073 // Must ACK back for the data received.
2750074 //
2750075 // The remote sequence that we will expect next time
2750076 // and the local sequence, expected from the other
2750077 // side.
2750078 //
2750079 sock->tcp.rsq[++sock->tcp.rsqi] =
2750080 ntohl (tcphdr->seq) + recv_size;
2750081 sock->tcp.lsq[++sock->tcp.lsqi] = sock->tcp.lsq_ack;
2750082 //
2750083 tcp_tx_ack (sock);
2750084 //
2750085 // Now the received data, if any, is to be read.
2750086 //
2750087 sock->tcp.can_recv = 0;
2750088 sock->tcp.can_read = 1;
2750089 //
2750090 //
2750091 //
2750092 return (0);
2750093 }
|
|
94.12.46
kernel/net/tcp/tcp_show.c
Si veda la sezione 93.23.
2760001 #include <kernel/net.h>
2760002 #include <kernel/net/ip.h>
2760003 #include <kernel/net/route.h>
2760004 #include <kernel/net/tcp.h>
2760005 #include <sys/os32.h>
2760006 #include <kernel/lib_k.h>
2760007 #include <kernel/fs.h>
2760008 #include <errno.h>
2760009 #include <arpa/inet.h>
2760010 #include <netinet/in.h>
2760011 #include <netinet/tcp.h>
2760012 //----------------------------------------------------------
2760013 void
2760014 tcp_show (h_addr_t src, h_addr_t dst,
2760015 const struct tcphdr *tcphdr)
2760016 {
2760017 struct in_addr addr_1;
2760018 struct in_addr addr_2;
2760019 char addr_string_1[INET_ADDRSTRLEN];
2760020 char addr_string_2[INET_ADDRSTRLEN];
2760021 //
2760022 if (tcphdr == NULL)
2760023 {
2760024 return;
2760025 }
2760026 //
2760027 addr_1.s_addr = htonl (src);
2760028 addr_2.s_addr = htonl (dst);
2760029 inet_ntop (AF_INET, &addr_1, addr_string_1,
2760030 (socklen_t) sizeof (addr_string_1));
2760031 inet_ntop (AF_INET, &addr_2, addr_string_2,
2760032 (socklen_t) sizeof (addr_string_2));
2760033 k_printf ("TCP %s:%i > %s:%i ", addr_string_1,
2760034 (unsigned int) ntohs (tcphdr->source),
2760035 addr_string_2,
2760036 (unsigned int) ntohs (tcphdr->dest));
2760037 k_printf ("s=%3u ", ntohl (tcphdr->seq));
2760038 k_printf ("k=%3u ", ntohl (tcphdr->ack_seq));
2760039
2760040 if (tcphdr->ack)
2760041 k_printf ("ack ");
2760042 if (tcphdr->psh)
2760043 k_printf ("psh ");
2760044 if (tcphdr->rst)
2760045 k_printf ("rst ");
2760046 if (tcphdr->syn)
2760047 k_printf ("syn ");
2760048 if (tcphdr->fin)
2760049 k_printf ("fin ");
2760050
2760051 k_printf ("\n");
2760052 }
|
|
94.12.47
kernel/net/tcp/tcp_status.c
Si veda la sezione 93.23.
2770001 #include <kernel/net.h>
2770002 #include <kernel/net/ip.h>
2770003 #include <kernel/net/route.h>
2770004 #include <kernel/net/tcp.h>
2770005 #include <sys/os32.h>
2770006 #include <kernel/lib_k.h>
2770007 #include <kernel/fs.h>
2770008 #include <errno.h>
2770009 #include <stdlib.h>
2770010 #include <arpa/inet.h>
2770011 #include <netinet/in.h>
2770012 #include <netinet/tcp.h>
2770013 //----------------------------------------------------------
2770014 int
2770015 tcp_status (void *ip_packet)
2770016 {
2770017 struct iphdr *iphdr;
2770018 struct tcphdr *tcphdr;
2770019 int s;
2770020 //
2770021 if (ip_packet == NULL)
2770022 {
2770023 errset (EINVAL);
2770024 return (-1);
2770025 }
2770026 //
2770027 iphdr = ip_packet;
2770028 tcphdr = (struct tcphdr *)
2770029 &(((uint8_t *) ip_packet)[iphdr->ihl * 4]);
2770030 //
2770031 if (iphdr->saddr == 0 || iphdr->daddr == 0)
2770032 {
2770033 errset (EINVAL);
2770034 return (-1);
2770035 }
2770036 //
2770037 if (tcphdr->source == 0 || tcphdr->dest == 0)
2770038 {
2770039 errset (EINVAL);
2770040 return (-1);
2770041 }
2770042 //
2770043 // Find a connection with the same IPs and ports.
2770044 //
2770045 for (s = 0; s < SOCK_MAX_SLOTS; s++)
2770046 {
2770047 if (!sock_table[s].active)
2770048 continue;
2770049 if (sock_table[s].family != AF_INET)
2770050 continue;
2770051 if (sock_table[s].protocol != IPPROTO_TCP)
2770052 continue;
2770053 if (sock_table[s].unreach_port)
2770054 continue;
2770055 if (sock_table[s].unreach_host)
2770056 continue;
2770057 if (sock_table[s].laddr != ntohl (iphdr->daddr))
2770058 continue;
2770059 if (sock_table[s].lport != ntohs (tcphdr->dest))
2770060 continue;
2770061 if (sock_table[s].raddr != ntohl (iphdr->saddr))
2770062 continue;
2770063 if (sock_table[s].rport != ntohs (tcphdr->source))
2770064 continue;
2770065 //
2770066 // A corresponding socket was found.
2770067 //
2770068 return ((int) sock_table[s].tcp.conn);
2770069 }
2770070 //
2770071 // Socket not found.
2770072 //
2770073 return (0);
2770074 }
|
|
94.12.48
kernel/net/tcp/tcp_test.c
Si veda la sezione 93.23.
2780001 #include <kernel/driver/pci.h>
2780002 #include <kernel/net/ip.h>
2780003 #include <kernel/net/tcp.h>
2780004 #include <kernel/net.h>
2780005 #include <kernel/ibm_i386.h>
2780006 #include <errno.h>
2780007 #include <kernel/lib_k.h>
2780008 #include <kernel/lib_s.h>
2780009 #include <stdint.h>
2780010 //----------------------------------------------------------
2780011 void
2780012 tcp_test (void)
2780013 {
2780014
2780015 h_addr_t src = 0xAC150B10; // 172, 21, 11, 16
2780016 h_addr_t dst = 0xAC150B0F; // 172, 21, 11, 15
2780017
2780018 int status;
2780019 //
2780020 //
2780021 //
2780022 status = tcp_tx_raw (12345, 1234, 100000, 0,
2780023 TCP_FLAG_SYN,
2780024 src, dst, "SYN", (size_t) 4);
2780025
2780026 if (status)
2780027 {
2780028 k_perror (NULL);
2780029 }
2780030 }
|
|
94.12.49
kernel/net/tcp/tcp_tx_ack.c
Si veda la sezione 93.23.
2790001 #include <kernel/net.h>
2790002 #include <kernel/net/ip.h>
2790003 #include <kernel/net/route.h>
2790004 #include <kernel/net/tcp.h>
2790005 #include <sys/os32.h>
2790006 #include <kernel/lib_k.h>
2790007 #include <kernel/fs.h>
2790008 #include <errno.h>
2790009 #include <arpa/inet.h>
2790010 #include <netinet/in.h>
2790011 #include <netinet/tcp.h>
2790012 //----------------------------------------------------------
2790013 #define DEBUG 0
2790014 //----------------------------------------------------------
2790015 int
2790016 tcp_tx_ack (void *sock_item)
2790017 {
2790018 sock_t *sock = sock_item;
2790019 tcp_packet_t packet;
2790020 tcp_pseudo_header_t pseudo;
2790021 uint16_t checksum;
2790022 //
2790023 if (sock == NULL)
2790024 {
2790025 errset (EINVAL);
2790026 return (-1);
2790027 }
2790028 if (sock->laddr == 0 || sock->raddr == 0)
2790029 {
2790030 errset (EINVAL);
2790031 return (-1);
2790032 }
2790033 if (sock->lport == 0 || sock->rport == 0)
2790034 {
2790035 errset (EINVAL);
2790036 return (-1);
2790037 }
2790038 //
2790039 // Prepare the TCP packet.
2790040 //
2790041 memset (&packet.header, 0, sizeof (struct tcphdr));
2790042 //
2790043 packet.header.source = htons (sock->lport);
2790044 packet.header.dest = htons (sock->rport);
2790045 packet.header.seq = htonl (sock->tcp.lsq[sock->tcp.lsqi]);
2790046 packet.header.ack_seq =
2790047 htonl (sock->tcp.rsq[sock->tcp.rsqi]);
2790048 packet.header.doff = (sizeof (struct tcphdr) / 4);
2790049 packet.header.ack = 1;
2790050 packet.header.window = htons (TCP_MSS); // Minimal
2790051 // window
2790052 packet.header.check = 0;
2790053 //
2790054 // Prepare the pseudo header.
2790055 //
2790056 pseudo.saddr = htonl (sock->laddr);
2790057 pseudo.daddr = htonl (sock->raddr);
2790058 pseudo.zero = 0;
2790059 pseudo.protocol = IPPROTO_TCP;
2790060 pseudo.length = htons (sizeof (struct tcphdr));
2790061 //
2790062 // Now set the header checksum.
2790063 //
2790064 checksum =
2790065 ~(ip_checksum
2790066 ((void *) &packet, sizeof (struct tcphdr),
2790067 (void *) &pseudo, sizeof (tcp_pseudo_header_t)));
2790068 if (checksum == 0)
2790069 {
2790070 checksum = 0xFFFF;
2790071 }
2790072 packet.header.check = htons (checksum);
2790073 //
2790074 // Send to the lower network level.
2790075 //
2790076 if (DEBUG)
2790077 {
2790078 tcp_show (sock->laddr, sock->raddr,
2790079 (struct tcphdr *) &packet);
2790080 }
2790081 return (ip_tx
2790082 (sock->laddr, sock->raddr, (int) IPPROTO_TCP,
2790083 &packet, sizeof (struct tcphdr)));
2790084 }
|
|
94.12.50
kernel/net/tcp/tcp_tx_raw.c
Si veda la sezione 93.23.
2800001 #include <kernel/net.h>
2800002 #include <kernel/net/ip.h>
2800003 #include <kernel/net/route.h>
2800004 #include <kernel/net/tcp.h>
2800005 #include <sys/os32.h>
2800006 #include <kernel/lib_k.h>
2800007 #include <errno.h>
2800008 #include <arpa/inet.h>
2800009 #include <netinet/tcp.h>
2800010 //----------------------------------------------------------
2800011 #define DEBUG 0
2800012 //----------------------------------------------------------
2800013 int
2800014 tcp_tx_raw (h_port_t sport, h_port_t dport,
2800015 uint32_t seq, uint32_t ack_seq, int flags,
2800016 h_addr_t saddr, h_addr_t daddr,
2800017 const void *buffer, size_t size)
2800018 {
2800019 tcp_packet_t packet;
2800020 tcp_pseudo_header_t pseudo;
2800021 uint16_t checksum;
2800022 size_t tcp_size = size + sizeof (struct tcphdr);
2800023 //
2800024 // Verify to have the source address: it is
2800025 // necessary here for
2800026 // the checksum calculation.
2800027 //
2800028 if (saddr == 0)
2800029 {
2800030 //
2800031 // Default source address: get the source
2800032 // address from the routing
2800033 // table, based on the destination.
2800034 //
2800035 saddr = route_remote_to_local (daddr);
2800036 if (saddr == ((h_addr_t) - 1))
2800037 {
2800038 errset (errno);
2800039 return (-1);
2800040 }
2800041 }
2800042 //
2800043 // Prepare the TCP packet.
2800044 //
2800045 memset (&packet.header, 0, sizeof (struct tcphdr));
2800046 //
2800047 packet.header.source = htons (sport);
2800048 packet.header.dest = htons (dport);
2800049 packet.header.seq = htonl (seq);
2800050 packet.header.ack_seq = htonl (ack_seq);
2800051 packet.header.doff = (sizeof (struct tcphdr) / 4);
2800052 if (flags & TCP_FLAG_ACK)
2800053 packet.header.ack = 1;
2800054 if (flags & TCP_FLAG_PSH)
2800055 packet.header.psh = 1;
2800056 if (flags & TCP_FLAG_RST)
2800057 packet.header.rst = 1;
2800058 if (flags & TCP_FLAG_SYN)
2800059 packet.header.syn = 1;
2800060 if (flags & TCP_FLAG_FIN)
2800061 packet.header.fin = 1;
2800062 if (flags & TCP_FLAG_RST)
2800063 {
2800064 packet.header.window = htons (0);
2800065 }
2800066 else
2800067 {
2800068 //
2800069 // Minimal window.
2800070 //
2800071 packet.header.window = htons (TCP_MSS);
2800072 }
2800073 packet.header.check = 0;
2800074 //
2800075 memcpy (packet.data, buffer, size);
2800076 //
2800077 // Prepare the pseudo header.
2800078 //
2800079 pseudo.saddr = htonl (saddr);
2800080 pseudo.daddr = htonl (daddr);
2800081 pseudo.zero = 0;
2800082 pseudo.protocol = IPPROTO_TCP;
2800083 pseudo.length = htons (tcp_size);
2800084 //
2800085 // Now set the header checksum.
2800086 //
2800087 checksum = ~(ip_checksum ((void *) &packet, tcp_size,
2800088 (void *) &pseudo,
2800089 sizeof (tcp_pseudo_header_t)));
2800090 if (checksum == 0)
2800091 {
2800092 checksum = 0xFFFF;
2800093 }
2800094 packet.header.check = htons (checksum);
2800095 //
2800096 // Send to the lower network level.
2800097 //
2800098 return (ip_tx
2800099 (saddr, daddr, (int) IPPROTO_TCP, &packet,
2800100 tcp_size));
2800101 }
|
|
94.12.51
kernel/net/tcp/tcp_tx_rst.c
Si veda la sezione 93.23.
2810001 #include <kernel/net.h>
2810002 #include <kernel/net/ip.h>
2810003 #include <kernel/net/route.h>
2810004 #include <kernel/net/tcp.h>
2810005 #include <sys/os32.h>
2810006 #include <kernel/lib_k.h>
2810007 #include <kernel/fs.h>
2810008 #include <errno.h>
2810009 #include <stdlib.h>
2810010 #include <arpa/inet.h>
2810011 #include <netinet/in.h>
2810012 #include <netinet/tcp.h>
2810013 //----------------------------------------------------------
2810014 #define DEBUG 0
2810015 //----------------------------------------------------------
2810016 int
2810017 tcp_tx_rst (void *ip_packet)
2810018 {
2810019 struct iphdr *iphdr = ip_packet;
2810020 struct tcphdr *tcphdr;
2810021 uint32_t seq;
2810022 uint32_t ack_seq;
2810023 tcp_packet_t packet;
2810024 tcp_pseudo_header_t pseudo;
2810025 uint16_t checksum;
2810026 //
2810027 if (ip_packet == NULL)
2810028 {
2810029 errset (EINVAL);
2810030 return (-1);
2810031 }
2810032 //
2810033 iphdr = ip_packet;
2810034 tcphdr = (struct tcphdr *)
2810035 &(((uint8_t *) ip_packet)[iphdr->ihl * 4]);
2810036 //
2810037 if (iphdr->saddr == 0 || iphdr->daddr == 0)
2810038 {
2810039 errset (EINVAL);
2810040 return (-1);
2810041 }
2810042 //
2810043 if (tcphdr->source == 0 || tcphdr->dest == 0)
2810044 {
2810045 errset (EINVAL);
2810046 return (-1);
2810047 }
2810048 //
2810049 // If the bad TCP packet has a ACK sequence, we
2810050 // replay with
2810051 // the same sequence (the one that the other side
2810052 // expects).
2810053 //
2810054 if (tcphdr->ack)
2810055 {
2810056 seq = ntohl (tcphdr->ack_seq);
2810057 }
2810058 else
2810059 {
2810060 seq = rand ();
2810061 }
2810062 //
2810063 // Our reset ACK has the same sequence received.
2810064 //
2810065 ack_seq = ntohl (tcphdr->seq);
2810066 //
2810067 // Prepare the TCP packet.
2810068 //
2810069 memset (&packet.header, 0, sizeof (struct tcphdr));
2810070 //
2810071 packet.header.source = tcphdr->dest;
2810072 packet.header.dest = tcphdr->source;
2810073 packet.header.seq = htonl (seq);
2810074 packet.header.ack_seq = htonl (ack_seq);
2810075 packet.header.doff = (sizeof (struct tcphdr) / 4);
2810076 packet.header.ack = 1;
2810077 packet.header.rst = 1;
2810078 packet.header.window = 0;
2810079 packet.header.check = 0;
2810080 //
2810081 // Prepare the pseudo header.
2810082 //
2810083 pseudo.saddr = iphdr->saddr;
2810084 pseudo.daddr = iphdr->daddr;
2810085 pseudo.zero = 0;
2810086 pseudo.protocol = IPPROTO_TCP;
2810087 pseudo.length = htons (sizeof (struct tcphdr));
2810088 //
2810089 // Now set the header checksum.
2810090 //
2810091 checksum =
2810092 ~(ip_checksum
2810093 ((void *) &packet, sizeof (struct tcphdr),
2810094 (void *) &pseudo, sizeof (tcp_pseudo_header_t)));
2810095 if (checksum == 0)
2810096 {
2810097 checksum = 0xFFFF;
2810098 }
2810099 packet.header.check = htons (checksum);
2810100 //
2810101 // Send to the lower network level.
2810102 //
2810103 if (DEBUG)
2810104 {
2810105 tcp_show (ntohl (iphdr->saddr),
2810106 ntohl (iphdr->daddr),
2810107 (struct tcphdr *) &packet);
2810108 }
2810109 return (ip_tx
2810110 (ntohl (iphdr->saddr), ntohl (iphdr->daddr),
2810111 IPPROTO_TCP, &packet, sizeof (struct tcphdr)));
2810112 }
|
|
94.12.52
kernel/net/tcp/tcp_tx_sock.c
Si veda la sezione 93.23.
2820001 #include <kernel/net.h>
2820002 #include <kernel/net/ip.h>
2820003 #include <kernel/net/route.h>
2820004 #include <kernel/net/tcp.h>
2820005 #include <sys/os32.h>
2820006 #include <kernel/lib_k.h>
2820007 #include <kernel/fs.h>
2820008 #include <errno.h>
2820009 #include <arpa/inet.h>
2820010 #include <netinet/in.h>
2820011 #include <netinet/tcp.h>
2820012 //----------------------------------------------------------
2820013 #define DEBUG 0
2820014 //----------------------------------------------------------
2820015 int
2820016 tcp_tx_sock (void *sock_item)
2820017 {
2820018 sock_t *sock = sock_item;
2820019 tcp_packet_t packet;
2820020 tcp_pseudo_header_t pseudo;
2820021 uint16_t checksum;
2820022 size_t tcp_size;
2820023 uint32_t seq;
2820024 uint32_t ack_seq;
2820025 size_t send_size;
2820026 //
2820027 if (sock == NULL)
2820028 {
2820029 errset (EINVAL);
2820030 return (-1);
2820031 }
2820032 if (!sock->tcp.can_send)
2820033 {
2820034 errset (EINVAL);
2820035 return (-1);
2820036 }
2820037 if (sock->laddr == 0 || sock->raddr == 0)
2820038 {
2820039 errset (EINVAL);
2820040 return (-1);
2820041 }
2820042 if (sock->lport == 0 || sock->rport == 0)
2820043 {
2820044 errset (EINVAL);
2820045 return (-1);
2820046 }
2820047 //
2820048 // Sequences and size.
2820049 //
2820050 seq = sock->tcp.lsq[sock->tcp.lsqi];
2820051 if ((sock->tcp.send_flags & TCP_FLAG_SYN)
2820052 || (sock->tcp.send_flags & TCP_FLAG_FIN))
2820053 {
2820054 //
2820055 // A SYN or FIN packet cannot load data.
2820056 //
2820057 send_size = 0;
2820058 //
2820059 // The next expected ACK from the other side is
2820060 // just
2820061 // +1.
2820062 //
2820063 sock->tcp.lsq_ack = seq + 1;
2820064 }
2820065 else
2820066 {
2820067 send_size = sock->tcp.send_size;
2820068 //
2820069 // The next expected ACK from the other side is
2820070 // + size of the sent data.
2820071 //
2820072 sock->tcp.lsq_ack = seq + send_size;
2820073 }
2820074 //
2820075 if (sock->tcp.send_flags & TCP_FLAG_ACK)
2820076 {
2820077 ack_seq = sock->tcp.rsq[sock->tcp.rsqi];
2820078 }
2820079 else
2820080 {
2820081 ack_seq = 0;
2820082 }
2820083 //
2820084 // Prepare the TCP packet.
2820085 //
2820086 memset (&packet.header, 0, sizeof (struct tcphdr));
2820087 //
2820088 packet.header.source = htons (sock->lport);
2820089 packet.header.dest = htons (sock->rport);
2820090 packet.header.seq = htonl (seq);
2820091 packet.header.ack_seq = htonl (ack_seq);
2820092 packet.header.doff = (sizeof (struct tcphdr) / 4);
2820093 if (sock->tcp.send_flags & TCP_FLAG_ACK)
2820094 packet.header.ack = 1;
2820095 if (sock->tcp.send_flags & TCP_FLAG_PSH)
2820096 packet.header.psh = 1;
2820097 if (sock->tcp.send_flags & TCP_FLAG_RST)
2820098 packet.header.rst = 1;
2820099 if (sock->tcp.send_flags & TCP_FLAG_SYN)
2820100 packet.header.syn = 1;
2820101 if (sock->tcp.send_flags & TCP_FLAG_FIN)
2820102 packet.header.fin = 1;
2820103 if (sock->tcp.send_flags & TCP_FLAG_RST)
2820104 {
2820105 packet.header.window = htons (0);
2820106 }
2820107 else
2820108 {
2820109 //
2820110 // Minimal window.
2820111 //
2820112 packet.header.window = htons (TCP_MSS);
2820113 }
2820114 packet.header.check = 0;
2820115 //
2820116 memcpy (packet.data, sock->tcp.send_data, send_size);
2820117 //
2820118 tcp_size = sizeof (struct tcphdr) + send_size;
2820119 //
2820120 // Prepare the pseudo header.
2820121 //
2820122 pseudo.saddr = htonl (sock->laddr);
2820123 pseudo.daddr = htonl (sock->raddr);
2820124 pseudo.zero = 0;
2820125 pseudo.protocol = IPPROTO_TCP;
2820126 pseudo.length = htons (tcp_size);
2820127 //
2820128 // Now set the header checksum.
2820129 //
2820130 checksum = ~(ip_checksum ((void *) &packet, tcp_size,
2820131 (void *) &pseudo,
2820132 sizeof (tcp_pseudo_header_t)));
2820133 if (checksum == 0)
2820134 {
2820135 checksum = 0xFFFF;
2820136 }
2820137 packet.header.check = htons (checksum);
2820138 //
2820139 // Send to the lower network level.
2820140 //
2820141 if (DEBUG)
2820142 {
2820143 tcp_show (sock->laddr, sock->raddr,
2820144 (struct tcphdr *) &packet);
2820145 }
2820146 sock->tcp.clock = s_clock ((pid_t) 0);
2820147 return (ip_tx
2820148 (sock->laddr, sock->raddr, (int) IPPROTO_TCP,
2820149 &packet, tcp_size));
2820150 }
|
|
94.12.53
kernel/net/udp.h
Si veda la sezione 93.23.
2830001 #ifndef _KERNEL_NET_UDP_H
2830002 #define _KERNEL_NET_UDP_H 1
2830003 //----------------------------------------------------------
2830004 #include <netinet/udp.h>
2830005 #include <kernel/net.h>
2830006 //----------------------------------------------------------
2830007 #define UDP_HEADER_SIZE 8
2830008 #define UDP_MAX_PACKET_SIZE NET_IP_MAX_DATA_SIZE
2830009 #define UDP_MAX_DATA_SIZE \
2830010 UDP_MAX_PACKET_SIZE-UDP_HEADER_SIZE
2830011 //----------------------------------------------------------
2830012 //
2830013 // UDP packet, for transmission.
2830014 //
2830015 typedef struct
2830016 {
2830017 struct udphdr header;
2830018 uint8_t data[UDP_MAX_DATA_SIZE];
2830019 } __attribute__ ((packed)) udp_packet_t;
2830020 //
2830021 // UDP pseudo header for checksum calculation.
2830022 //
2830023 typedef struct
2830024 {
2830025 in_addr_t saddr;
2830026 in_addr_t daddr;
2830027 uint8_t zero;
2830028 uint8_t protocol;
2830029 uint16_t length;
2830030 } __attribute__ ((packed)) udp_pseudo_header_t;
2830031 //----------------------------------------------------------
2830032 int udp_tx (h_port_t sport, h_port_t dport,
2830033 h_addr_t saddr, h_addr_t daddr,
2830034 const void *buffer, size_t size);
2830035 //----------------------------------------------------------
2830036 #endif
|
|
94.12.54
kernel/net/udp/udp_tx.c
Si veda la sezione 93.23.
2840001 #include <kernel/net.h>
2840002 #include <kernel/net/ip.h>
2840003 #include <kernel/net/route.h>
2840004 #include <kernel/net/udp.h>
2840005 #include <sys/os32.h>
2840006 #include <kernel/lib_k.h>
2840007 #include <errno.h>
2840008 #include <arpa/inet.h>
2840009 #include <netinet/udp.h>
2840010 //----------------------------------------------------------
2840011 #define DEBUG 0
2840012 //----------------------------------------------------------
2840013 int
2840014 udp_tx (h_port_t sport, h_port_t dport, h_addr_t saddr,
2840015 h_addr_t daddr, const void *buffer, size_t size)
2840016 {
2840017 udp_packet_t packet;
2840018 udp_pseudo_header_t pseudo;
2840019 uint16_t checksum;
2840020 size_t udp_size = size + sizeof (struct udphdr);
2840021 //
2840022 // Verify to have the source address: it is
2840023 // necessary here for
2840024 // the checksum calculation.
2840025 //
2840026 if (saddr == 0)
2840027 {
2840028 //
2840029 // Default source address: get the source
2840030 // address from the routing
2840031 // table, based on the destination.
2840032 //
2840033 saddr = route_remote_to_local (daddr);
2840034 if (saddr == ((h_addr_t) - 1))
2840035 {
2840036 errset (errno);
2840037 return (-1);
2840038 }
2840039 }
2840040 //
2840041 // Prepare the UDP packet.
2840042 //
2840043 packet.header.source = htons (sport);
2840044 packet.header.dest = htons (dport);
2840045 packet.header.len = htons (udp_size);
2840046 packet.header.check = 0;
2840047 memcpy (packet.data, buffer, size);
2840048 //
2840049 // Prepare the pseudo header.
2840050 //
2840051 pseudo.saddr = htonl (saddr);
2840052 pseudo.daddr = htonl (daddr);
2840053 pseudo.zero = 0;
2840054 pseudo.protocol = IPPROTO_UDP;
2840055 pseudo.length = htons (udp_size);
2840056 //
2840057 // Now set the header checksum.
2840058 //
2840059 checksum = ~(ip_checksum ((void *) &packet, udp_size,
2840060 (void *) &pseudo,
2840061 sizeof (udp_pseudo_header_t)));
2840062 if (checksum == 0)
2840063 {
2840064 checksum = 0xFFFF;
2840065 }
2840066 packet.header.check = htons (checksum);
2840067 //
2840068 // Send to the lower network level.
2840069 //
2840070 return (ip_tx
2840071 (saddr, daddr, (int) IPPROTO_UDP, &packet,
2840072 udp_size));
2840073 }
|
|
94.13
os32: «kernel/part.h»
Si veda la sezione 93.18.
2850001 #ifndef _KERNEL_PART_H
2850002 #define _KERNEL_PART_H 1
2850003
2850004
2850005 typedef struct
2850006 {
2850007 uint8_t active; // boot indicator 0 or
2850008 // PART_ACTIVE
2850009 uint8_t h_start; // head value for first sector
2850010 uint8_t s_start; // sector value + cyl bits for
2850011 // first sector
2850012 uint8_t c_start; // track value for first
2850013 // sector
2850014 uint8_t type; // partition type
2850015 uint8_t h_last; // head value for last sector
2850016 uint8_t s_last; // sector value + cyl bits for
2850017 // last sector
2850018 uint8_t c_last; // track value for last sector
2850019 uint32_t l_start; // logical first sector
2850020 uint32_t size; // size of partition in
2850021 // sectors
2850022 } part_t;
2850023
2850024 #define PART_ACTIVE 0x80 // value for active
2850025 // partition
2850026 #define PART_MAX 4 // number of entries
2850027 // in partition table
2850028 #define PART_TABLE_OFF 0x1BE // offset of part.
2850029 // table in boot
2850030 // sector
2850031
2850032 //
2850033 // Partition types.
2850034 //
2850035 #define PART_TYPE_NONE 0x00 // unused
2850036 // entry
2850037 #define PART_TYPE_NO_PART 0xFF // full device
2850038 #define PART_TYPE_MINIX 0x81 // Minix
2850039 // partition
2850040 // type
2850041 #define PART_TYPE_OLDMINIX 0x80 // Minix 1 old
2850042 // partition
2850043 // type
2850044 #define PART_TYPE_EXT 0x05 // extended
2850045 // partition
2850046
2850047
2850048 #endif
|
|
94.14
os32: «kernel/proc.h»
Si veda la sezione 93.20.
2860001 #ifndef _KERNEL_PROC_H
2860002 #define _KERNEL_PROC_H 1
2860003 //----------------------------------------------------------
2860004 #include <kernel/ibm_i386.h>
2860005 #include <kernel/dev.h>
2860006 #include <kernel/driver/tty.h>
2860007 #include <sys/types.h>
2860008 #include <sys/stat.h>
2860009 #include <kernel/fs.h>
2860010 #include <sys/os32.h>
2860011 #include <stddef.h>
2860012 #include <stdint.h>
2860013 #include <time.h>
2860014 //----------------------------------------------------------
2860015 #define CLOCK_FREQUENCY_DIVISOR \
2860016 (3579545/3/CLOCKS_PER_SEC) // [1]
2860017 //
2860018 // [1] Internal clock frequency is (3579545/3) Hz.
2860019 // This value is divided by
2860020 // CLOCK_FREQUENCY_DIVISOR, giving 100 Hz.
2860021 // The divisor value if fixed, because the code
2860022 // suppose that the clock frequency is 100 Hz!
2860023 //
2860024 //----------------------------------------------------------
2860025 #define PROC_EMPTY 0
2860026 #define PROC_CREATED 1
2860027 #define PROC_READY 2
2860028 #define PROC_RUNNING 3
2860029 #define PROC_SLEEPING 4
2860030 #define PROC_ZOMBIE 5
2860031 //----------------------------------------------------------
2860032 #define MAGIC_OS32_APPL 0x6F7333326170706CLL // [2]
2860033 //
2860034 // [2] os32appl
2860035 //
2860036 //----------------------------------------------------------
2860037 #define PROCESS_MAX ((GDT_ITEMS/2)-1) // Process
2860038 // slots.
2860039 #define MAX_SIGNALS 31 // Max signal number.
2860040 //
2860041 typedef struct
2860042 {
2860043 pid_t ppid; // Parent PID.
2860044 pid_t pgrp; // Process group ID.
2860045 uid_t uid; // Real user ID
2860046 uid_t euid; // Effective user ID.
2860047 uid_t suid; // Saved user ID.
2860048 gid_t gid; // Real group ID
2860049 gid_t egid; // Effective group ID.
2860050 gid_t sgid; // Saved group ID.
2860051 dev_t device_tty; // Controlling terminal.
2860052 char path_cwd[PATH_MAX];
2860053 // Working directory path.
2860054 inode_t *inode_cwd; // Working directory inode.
2860055 int umask; // File creation mask.
2860056 unsigned long int sig_status; // Active signals.
2860057 unsigned long int sig_ignore; // Signals to be
2860058 // ignored.
2860059 uintptr_t sig_handler[MAX_SIGNALS]; // Opt. sig.
2860060 // handlers.
2860061 uintptr_t sig_handler_wrapper; // Special
2860062 // wrapper.
2860063 clock_t usage; // Clock ticks CPU time usage.
2860064 unsigned int status;
2860065 int wakeup_events; // Wake up for something.
2860066 int wakeup_signal; // Signal waited.
2860067 unsigned int wakeup_timer; // Seconds to wait
2860068 // for.
2860069 inode_t *wakeup_inode; // Inode waited.
2860070 sock_t *wakeup_sock; // Socket waited.
2860071 dev_t wakeup_dev; // Device waited.
2860072 addr_t address_text;
2860073 size_t domain_text;
2860074 addr_t address_data;
2860075 size_t domain_data;
2860076 size_t domain_stack; // Included inside the data.
2860077 size_t extra_data; // Extra data for `brk()'.
2860078 uint32_t sp;
2860079 int ret;
2860080 char name[PATH_MAX];
2860081 fd_t fd[FOPEN_MAX];
2860082 } proc_t;
2860083 //
2860084 extern proc_t proc_table[PROCESS_MAX];
2860085 //
2860086 // ATTENTION: THERE IS NO WAY TO KEEP THE STACK DOMAIN
2860087 // IN A DIFFERENT ADDRESS SPACE THAN THE
2860088 // OTHER DATA. There is a simple explanation
2860089 // for such limitation: A POINTER TO DATA
2860090 // INSIDE THE STACK, CANNOT BE REACHED IF IT
2860091 // IS NOT INSIDE THE SAME ADDRESS SPACE!
2860092 //
2860093 // For the same reason, data or stack,
2860094 // cannot be moved (shifted) down, when more
2860095 // space is needed, because previous
2860096 // pointers would not work! So, to develop
2860097 // an extensible `malloc' area, such memory
2860098 // is to be placed *after* the stack, moving
2860099 // *all* the data segment if necessary.
2860100 //----------------------------------------------------------
2860101 extern pid_t proc_current;
2860102 extern uint32_t proc_stack_pointer;
2860103 extern uint16_t proc_stack_segment_selector;
2860104 extern unsigned int proc_loops_per_clock;
2860105 //----------------------------------------------------------
2860106 typedef struct
2860107 {
2860108 uint32_t filler0;
2860109 uint64_t magic;
2860110 uint32_t data_offset;
2860111 uint32_t etext;
2860112 uint32_t edata;
2860113 uint32_t ebss;
2860114 uint32_t ssize;
2860115 } header_t;
2860116 //----------------------------------------------------------
2860117 typedef struct
2860118 {
2860119 uint32_t eax;
2860120 uint32_t ecx;
2860121 uint32_t edx;
2860122 uint32_t ebx;
2860123 uint32_t ebp;
2860124 uint32_t esi;
2860125 uint32_t edi;
2860126 uint32_t ds;
2860127 uint32_t es;
2860128 uint32_t fs;
2860129 uint32_t gs;
2860130 uint32_t eip;
2860131 uint32_t cs;
2860132 uint32_t eflags;
2860133 } stack_t;
2860134 //----------------------------------------------------------
2860135 void proc_init (void);
2860136 void proc_timer_init (clock_t freq);
2860137 void proc_delay (void);
2860138 void proc_scheduler (void);
2860139 void sysroutine (uint32_t syscallnr, uint32_t msg_off,
2860140 uint32_t msg_size);
2860141 //----------------------------------------------------------
2860142 void *ptr (pid_t pid, void *p);
2860143 proc_t *proc_reference (pid_t pid);
2860144 void proc_print (void);
2860145 //----------------------------------------------------------
2860146 int proc_sys_exec (pid_t pid, const char *path,
2860147 unsigned int argc, char *arg_data,
2860148 unsigned int envc, char *env_data);
2860149 //----------------------------------------------------------
2860150 void proc_dump_memory (pid_t pid, addr_t address,
2860151 size_t size, char *name);
2860152 void proc_available (pid_t pid);
2860153 void proc_sch_net (void);
2860154 void proc_sch_signals (void);
2860155 void proc_sch_terminals (void);
2860156 void proc_sch_timers (void);
2860157 void proc_sig_chld (pid_t parent, int sig);
2860158 void proc_sig_cont (pid_t pid, int sig);
2860159 void proc_sig_core (pid_t pid, int sig);
2860160 void proc_sig_handler (pid_t pid, int sig);
2860161 int proc_sig_ignore (pid_t pid, int sig);
2860162 void proc_sig_off (pid_t pid, int sig);
2860163 void proc_sig_on (pid_t pid, int sig);
2860164 int proc_sig_status (pid_t pid, int sig);
2860165 void proc_sig_stop (pid_t pid, int sig);
2860166 void proc_sig_term (pid_t pid, int sig);
2860167
2860168 void proc_wakeup_pipe_read (inode_t * inode);
2860169 void proc_wakeup_pipe_write (inode_t * inode);
2860170 void proc_wakeup_terminal (void);
2860171
2860172 #endif
|
|
94.14.1
kernel/proc/proc_available.c
Si veda la sezione 93.20.1.
2870001 #include <kernel/proc.h>
2870002 //----------------------------------------------------------
2870003 void
2870004 proc_available (pid_t pid)
2870005 {
2870006 proc_table[pid].ppid = (pid_t) - 1;
2870007 proc_table[pid].pgrp = (pid_t) - 1;
2870008 proc_table[pid].uid = (uid_t) - 1;
2870009 proc_table[pid].euid = (uid_t) - 1;
2870010 proc_table[pid].suid = (uid_t) - 1;
2870011 proc_table[pid].gid = (gid_t) - 1;
2870012 proc_table[pid].egid = (gid_t) - 1;
2870013 proc_table[pid].sgid = (gid_t) - 1;
2870014 proc_table[pid].sig_status = 0;
2870015 proc_table[pid].sig_ignore = 0;
2870016 proc_table[pid].usage = (clock_t) 0;
2870017 proc_table[pid].status = PROC_EMPTY;
2870018 proc_table[pid].wakeup_events = 0;
2870019 proc_table[pid].wakeup_signal = 0;
2870020 proc_table[pid].wakeup_timer = 0;
2870021 proc_table[pid].wakeup_inode = NULL;
2870022 proc_table[pid].address_text = (addr_t) 0;
2870023 proc_table[pid].domain_text = (size_t) 0;
2870024 proc_table[pid].address_data = (addr_t) 0;
2870025 proc_table[pid].domain_data = (size_t) 0;
2870026 proc_table[pid].domain_stack = (size_t) 0;
2870027 proc_table[pid].extra_data = (size_t) 0;
2870028 proc_table[pid].sp = (uint32_t) 0;
2870029 proc_table[pid].ret = 0;
2870030 proc_table[pid].inode_cwd = NULL;
2870031 proc_table[pid].path_cwd[0] = 0;
2870032 proc_table[pid].umask = 0;
2870033 proc_table[pid].name[0] = 0;
2870034 }
|
|
94.14.2
kernel/proc/proc_dump_memory.c
Si veda la sezione 93.20.2.
2880001 #include <kernel/proc.h>
2880002 #include <fcntl.h>
2880003 #include <kernel/lib_s.h>
2880004 #include <kernel/lib_k.h>
2880005 //----------------------------------------------------------
2880006 void
2880007 proc_dump_memory (pid_t pid, addr_t address,
2880008 size_t size, char *name)
2880009 {
2880010 int fdn;
2880011 char buffer[BUFSIZ];
2880012 ssize_t size_written;
2880013 ssize_t size_written_total;
2880014 ssize_t size_read;
2880015 ssize_t size_read_total;
2880016 ssize_t size_total = 0;
2880017 //
2880018 // Dump the code segment to disk.
2880019 //
2880020 fdn =
2880021 s_open (pid, name, (O_WRONLY | O_CREAT | O_TRUNC),
2880022 (mode_t) (S_IFREG | 00644));
2880023 if (fdn < 0)
2880024 {
2880025 //
2880026 // There is a problem: just let it go.
2880027 //
2880028 k_perror (NULL);
2880029 return;
2880030 }
2880031 //
2880032 // Read the memory and write it to disk.
2880033 //
2880034 for (size_read = 0, size_read_total = 0;
2880035 size_read_total < size_total;
2880036 size_read_total += size_read, address += size_read)
2880037 {
2880038 size_read = dev_io ((pid_t) 0, DEV_MEM, DEV_READ,
2880039 (off_t) address, buffer,
2880040 (size_t) BUFSIZ, NULL);
2880041 //
2880042 for (size_written = 0, size_written_total = 0;
2880043 size_written_total < size_read;
2880044 size_written_total += size_written)
2880045 {
2880046 size_written = s_write
2880047 (pid, fdn,
2880048 &buffer
2880049 [size_written_total],
2880050 (size_t) (size_read - size_written_total));
2880051 //
2880052 if (size_written < 0)
2880053 {
2880054 s_close (pid, fdn);
2880055 return;
2880056 }
2880057 }
2880058 }
2880059 s_close (pid, fdn);
2880060 }
|
|
94.14.3
kernel/proc/proc_init.c
Si veda la sezione 93.20.3.
2890001 #include <kernel/ibm_i386.h>
2890002 #include <kernel/proc.h>
2890003 #include <kernel/lib_k.h>
2890004 #include <kernel/lib_s.h>
2890005 #include <string.h>
2890006 #include <kernel/multiboot.h>
2890007 #include <kernel/dm.h>
2890008 //----------------------------------------------------------
2890009 extern uint32_t _k_start;
2890010 extern uint32_t _k_end;
2890011 extern uint32_t _k_text_end;
2890012 extern uint32_t _k_data_end;
2890013 extern uint32_t _k_bss_end;
2890014 extern uint32_t _k_stack_top;
2890015 extern uint32_t _k_stack_bottom;
2890016 //----------------------------------------------------------
2890017 void
2890018 proc_init (void)
2890019 {
2890020 pid_t pid;
2890021 int fdn; // File descriptor index;
2890022 inode_t *inode;
2890023 sb_t *sb;
2890024 clock_t time_start;
2890025 clock_t time_now;
2890026 clock_t time_elapsed;
2890027 unsigned long long int count;
2890028 uintptr_t stack_top = (uintptr_t) & _k_stack_top;
2890029 uintptr_t stack_bottom = (uintptr_t) & _k_stack_bottom;
2890030 int sig;
2890031 //
2890032 // Set up the GDT table.
2890033 //
2890034 gdt ();
2890035 //
2890036 // Set up timer.
2890037 //
2890038 proc_timer_init (CLOCKS_PER_SEC);
2890039 //
2890040 // Disable external interrupt.
2890041 //
2890042 cli ();
2890043 //
2890044 // Set up the IDT table.
2890045 //
2890046 idt ();
2890047 //
2890048 // Set all memory reference to some invalid data.
2890049 //
2890050 for (pid = 0; pid < PROCESS_MAX; pid++)
2890051 {
2890052 proc_available (pid);
2890053 }
2890054 //
2890055 // Set up the process table with the kernel.
2890056 //
2890057 proc_table[0].ppid = 0;
2890058 proc_table[0].pgrp = 0;
2890059 proc_table[0].uid = 0;
2890060 proc_table[0].euid = 0;
2890061 proc_table[0].suid = 0;
2890062 proc_table[0].gid = 0;
2890063 proc_table[0].egid = 0;
2890064 proc_table[0].sgid = 0;
2890065 proc_table[0].device_tty = DEV_UNDEFINED;
2890066 proc_table[0].sig_status = 0;
2890067 proc_table[0].sig_ignore = 0;
2890068 proc_table[0].usage = 0;
2890069 proc_table[0].status = PROC_RUNNING;
2890070 proc_table[0].wakeup_events = 0;
2890071 proc_table[0].wakeup_signal = 0;
2890072 proc_table[0].wakeup_timer = 0;
2890073 proc_table[0].wakeup_inode = NULL;
2890074 proc_table[0].address_text = 0; // [1]
2890075 proc_table[0].domain_text = (size_t) (&_k_end); // [2]
2890076 proc_table[0].address_data = 0; // [2]
2890077 proc_table[0].domain_data = (size_t) 0; // [2]
2890078 proc_table[0].domain_stack =
2890079 (size_t) (stack_bottom - stack_top);
2890080 proc_table[0].extra_data = (size_t) 0;
2890081 proc_table[0].sp = 0; // [3]
2890082 proc_table[0].ret = 0;
2890083 proc_table[0].umask = 0022; // Default umask.
2890084 strncpy (proc_table[0].path_cwd, "/", PATH_MAX);
2890085 strncpy (proc_table[0].name, "os32 kernel", PATH_MAX);
2890086 //
2890087 // [1] The kernel text starts at 0x100000, that is,
2890088 // 1 Mibyte,
2890089 // but the code expect to start at that address,
2890090 // just like
2890091 // the space from address 0 to 0xFFFFF is anyway
2890092 // part
2890093 // of the kernel. If the kernel is forked, as it
2890094 // happens
2890095 // when the `init' process is to be run, it is
2890096 // necessary
2890097 // to consider part of the kernel all the addresses
2890098 // starting
2890099 // from zero.
2890100 //
2890101 // [2] The kernel is a unique block, where text and
2890102 // data live
2890103 // together.
2890104 //
2890105 // [3] The saved stack pointer location will be set
2890106 // at the
2890107 // next interrupt, or system call. That is why the
2890108 // kernel
2890109 // must send a null system call at the beginning of
2890110 // its
2890111 // work.
2890112 // ---------------------------------------------------
2890113 //
2890114 // Ensure to have a terminated string.
2890115 //
2890116 proc_table[0].name[PATH_MAX - 1] = 0;
2890117 //
2890118 // Reset file descriptors.
2890119 //
2890120 for (fdn = 0; fdn < OPEN_MAX; fdn++)
2890121 {
2890122 proc_table[0].fd[fdn].fl_flags = 0;
2890123 proc_table[0].fd[fdn].fd_flags = 0;
2890124 proc_table[0].fd[fdn].file = NULL;
2890125 }
2890126 //
2890127 // Reset `sig_handler[]'.
2890128 //
2890129 for (sig = 0; sig < MAX_SIGNALS; sig++)
2890130 {
2890131 proc_table[0].sig_handler[sig] = (uintptr_t) NULL;
2890132 }
2890133 //
2890134 // Allocate memory for the kernel.
2890135 //
2890136 // The BIOS data area (BDA) and extra BIOS at the
2890137 // bottom
2890138 // of 640 Kibyte, is already, formally, included
2890139 // inside the
2890140 // kernel.
2890141 //
2890142 // The allocation for data has no effect here,
2890143 // because it is
2890144 // the same as the text.
2890145 //
2890146 mb_alloc (proc_table[0].address_text,
2890147 proc_table[0].domain_text);
2890148 mb_alloc (proc_table[0].address_data,
2890149 proc_table[0].domain_data);
2890150 //
2890151 // Enable and disable hardware interrupts (IRQ).
2890152 //
2890153 irq_on (0); // timer.
2890154 irq_on (1); // keyboard
2890155 irq_on (2); // PIC2: keep it ON! [4]
2890156 irq_on (3); //
2890157 irq_on (4); //
2890158 irq_on (5); //
2890159 irq_on (6); //
2890160 irq_on (7); //
2890161 irq_on (8); //
2890162 irq_on (9); //
2890163 irq_on (10); //
2890164 irq_on (11); //
2890165 irq_on (12); //
2890166 irq_on (13); //
2890167 irq_on (14); //
2890168 irq_on (15); //
2890169 //
2890170 // [4] IRQ 2 must be let working, because inside the
2890171 // file
2890172 // `kernel/ibm_i386/isr_s', the IRQ 2 is used to
2890173 // reset
2890174 // properly PIC 1, so that, the IRQ from 8 to 15
2890175 // will
2890176 // reset only PIC 2.
2890177 // The problem is that any PIC must be reset exactly
2890178 // once, otherwise the system will lock.
2890179 //
2890180 //
2890181 // External interrupts activation.
2890182 //
2890183 sti ();
2890184 //
2890185 // Calculate how many times can be executed the
2890186 // following loop. This data will be used by
2890187 // `k_sleep()', if the clock pulse does not work
2890188 // for some reason.
2890189 //
2890190 time_elapsed = 0;
2890191 count = 0;
2890192 time_start = s_clock ((pid_t) 0);
2890193 for (; time_elapsed < 10; count++)
2890194 {
2890195 time_now = s_clock ((pid_t) 0);
2890196 time_elapsed = time_now - time_start;
2890197 }
2890198 proc_loops_per_clock = count / 10;
2890199 //
2890200 // Set up data-memory devices:
2890201 // it works only after enabling interrupts.
2890202 //
2890203 dm_init ();
2890204 //
2890205 // Mount root file system.
2890206 //
2890207 inode = NULL;
2890208 sb = sb_mount (DEV_DM02, &inode, MOUNT_DEFAULT);
2890209 if (sb == NULL || inode == NULL)
2890210 {
2890211 k_perror
2890212 ("Kernel panic: cannot mount " "root file system:");
2890213 k_exit ();
2890214 }
2890215 //
2890216 // Add the inode to the process table item for the
2890217 // kernel.
2890218 //
2890219 proc_table[0].inode_cwd = inode; // Root fs
2890220 // inode.
2890221 }
|
|
94.14.4
kernel/proc/proc_print.c
Si veda la sezione 93.20.4.
2900001 #include <sys/os32.h>
2900002 #include <kernel/proc.h>
2900003 #include <kernel/lib_k.h>
2900004 //----------------------------------------------------------
2900005 void
2900006 proc_print (void)
2900007 {
2900008 pid_t pid;
2900009 char stat;
2900010 unsigned int min;
2900011 unsigned int sec;
2900012 //
2900013 //
2900014 //
2900015 k_printf
2900016 ("pp p pg T * 0x1000 "
2900017 "D * 0x1000 stack \n"
2900018 "id id rp tty uid euid suid usage s addr size "
2900019 "addr size pointer name\n");
2900020 //
2900021 //
2900022 //
2900023 for (pid = 0; pid < PROCESS_MAX; pid++)
2900024 {
2900025 if (proc_table[pid].status > 0)
2900026 {
2900027 switch (proc_table[pid].status)
2900028 {
2900029 case PROC_EMPTY:
2900030 stat = '-';
2900031 break;
2900032 case PROC_CREATED:
2900033 stat = 'c';
2900034 break;
2900035 case PROC_READY:
2900036 stat = 'r';
2900037 break;
2900038 case PROC_RUNNING:
2900039 stat = 'R';
2900040 break;
2900041 case PROC_SLEEPING:
2900042 stat = 's';
2900043 break;
2900044 case PROC_ZOMBIE:
2900045 stat = 'z';
2900046 break;
2900047 default:
2900048 stat = '?';
2900049 break;
2900050 }
2900051 //
2900052 min =
2900053 ((proc_table[pid].usage / CLOCKS_PER_SEC) / 60);
2900054 sec =
2900055 ((proc_table[pid].usage / CLOCKS_PER_SEC) % 60);
2900056 //
2900057 // Addresses and sizes are multiple of 4096
2900058 // (0x1000);
2900059 // for the stack pointer is shown only the
2900060 // last five
2900061 // hexadecimal digits.
2900062 //
2900063 if (proc_table[pid].domain_data > 0)
2900064 {
2900065 k_printf
2900066 ("%2i %2i %2i %04x %4i %4i "
2900067 "%4i %02i.%02i %c "
2900068 "%05x %04x %05x %04x %07x %12s\n",
2900069 (unsigned int) proc_table[pid].ppid,
2900070 (unsigned int) pid,
2900071 (unsigned int) proc_table[pid].pgrp,
2900072 (unsigned int) proc_table[pid].device_tty,
2900073 (unsigned int) proc_table[pid].uid,
2900074 (unsigned int) proc_table[pid].euid,
2900075 (unsigned int) proc_table[pid].suid,
2900076 min, sec, stat,
2900077 (unsigned int) proc_table[pid].address_text
2900078 / MEM_BLOCK_SIZE,
2900079 (unsigned int) proc_table[pid].domain_text
2900080 / MEM_BLOCK_SIZE,
2900081 (unsigned int) proc_table[pid].address_data
2900082 / MEM_BLOCK_SIZE,
2900083 (unsigned int) (proc_table[pid].domain_data
2900084 +
2900085 proc_table[pid].extra_data)
2900086 / MEM_BLOCK_SIZE,
2900087 (unsigned int) proc_table[pid].sp,
2900088 proc_table[pid].name);
2900089 }
2900090 else
2900091 {
2900092 k_printf
2900093 ("%2i %2i %2i %04x %4i %4i %4i "
2900094 "%02i.%02i %c "
2900095 "%05x %04x %05x %04x %07x %12s\n",
2900096 (unsigned int) proc_table[pid].ppid,
2900097 (unsigned int) pid,
2900098 (unsigned int) proc_table[pid].pgrp,
2900099 (unsigned int) proc_table[pid].device_tty,
2900100 (unsigned int) proc_table[pid].uid,
2900101 (unsigned int) proc_table[pid].euid,
2900102 (unsigned int) proc_table[pid].suid,
2900103 min, sec, stat,
2900104 (unsigned int) proc_table[pid].address_text
2900105 / MEM_BLOCK_SIZE,
2900106 (unsigned int) (proc_table[pid].domain_text
2900107 +
2900108 proc_table[pid].extra_data)
2900109 / MEM_BLOCK_SIZE,
2900110 (unsigned int) proc_table[pid].address_data
2900111 / MEM_BLOCK_SIZE,
2900112 (unsigned int) proc_table[pid].domain_data
2900113 / MEM_BLOCK_SIZE,
2900114 (unsigned int) proc_table[pid].sp,
2900115 proc_table[pid].name);
2900116 }
2900117 }
2900118 }
2900119 }
|
|
94.14.5
kernel/proc/proc_public.c
Si veda la sezione 93.20.5.
2910001 #include <kernel/proc.h>
2910002 //----------------------------------------------------------
2910003 proc_t proc_table[PROCESS_MAX];
2910004 pid_t proc_current = 0;
2910005 uint16_t proc_stack_segment_selector = 24;
2910006 uint32_t proc_stack_pointer;
2910007 unsigned int proc_loops_per_clock;
|
|
94.14.6
kernel/proc/proc_reference.c
Si veda la sezione 93.20.5.
2920001 #include <kernel/proc.h>
2920002 //----------------------------------------------------------
2920003 proc_t *
2920004 proc_reference (pid_t pid)
2920005 {
2920006 if (pid >= 0 && pid < PROCESS_MAX)
2920007 {
2920008 return (&proc_table[pid]);
2920009 }
2920010 else
2920011 {
2920012 return (NULL);
2920013 }
2920014 }
|
|
94.14.7
kernel/proc/proc_sch_net.c
Si veda la sezione 93.20.6.
2930001 #include <kernel/proc.h>
2930002 #include <kernel/lib_k.h>
2930003 #include <kernel/lib_s.h>
2930004 #include <kernel/driver/nic/ne2k.h>
2930005 #include <kernel/net.h>
2930006 #include <kernel/driver/pci.h>
2930007 //----------------------------------------------------------
2930008 #define DEBUG 0
2930009 //----------------------------------------------------------
2930010 void
2930011 proc_sch_net (void)
2930012 {
2930013 int n; // NET table index.
2930014 int counter = 0;
2930015 int pid;
2930016 int tcp_wake_up;
2930017 //
2930018 // Do what there is to do with network interfaces,
2930019 // in particular get
2930020 // received frames, into the
2930021 // `net_table[n]...buffer[f]' table.
2930022 //
2930023 for (n = 0; n < NET_MAX_DEVICES; n++)
2930024 {
2930025 if (net_table[n].type == NET_DEV_ETH_NE2K)
2930026 {
2930027 //
2930028 // The function `ne2k_isr()' will call also
2930029 // `ne2k_rx()'
2930030 // that is responsible for placing Ethernet
2930031 // frames inside
2930032 // `ethernet_table[eth].frame_info[f]'.
2930033 //
2930034 ne2k_isr (net_table[n].ethernet.base_io);
2930035 }
2930036 else if (net_table[n].type == NET_DEV_LOOPBACK)
2930037 {
2930038 //
2930039 // Packets should be already inside the
2930040 // packet buffer table.
2930041 //
2930042 ;
2930043 }
2930044 }
2930045 //
2930046 // Do something with received Ethernet frames.
2930047 //
2930048 counter = net_rx ();
2930049 //
2930050 if (DEBUG)
2930051 {
2930052 if (counter)
2930053 {
2930054 k_printf ("+ %i packet(s) received\n", counter);
2930055 }
2930056 }
2930057 //
2930058 // Do something with TCP connections.
2930059 //
2930060 tcp_wake_up = tcp ();
2930061 //
2930062 // Wake up sleeping processes.
2930063 //
2930064 if (counter || tcp_wake_up == TCP_TRY_READ)
2930065 {
2930066 //
2930067 // Wake up sleeping processes, waiting to read
2930068 // from a socket.
2930069 //
2930070 if (DEBUG)
2930071 {
2930072 k_printf
2930073 ("wake up processes, waiting "
2930074 "for a socket!\n");
2930075 }
2930076 for (pid = 1; pid < PROCESS_MAX; pid++)
2930077 {
2930078 if (proc_table[pid].status == PROC_SLEEPING
2930079 && (proc_table[pid].wakeup_events
2930080 & WAKEUP_EVENT_SOCK_READ))
2930081 {
2930082 proc_table[pid].wakeup_events = 0;
2930083 proc_table[pid].status = PROC_READY;
2930084 }
2930085 }
2930086 }
2930087 //
2930088 if (tcp_wake_up == TCP_TRY_WRITE)
2930089 {
2930090 //
2930091 // Wake up sleeping processes, waiting to write
2930092 // to a socket.
2930093 //
2930094 for (pid = 1; pid < PROCESS_MAX; pid++)
2930095 {
2930096 if (proc_table[pid].status == PROC_SLEEPING
2930097 && (proc_table[pid].wakeup_events
2930098 & WAKEUP_EVENT_SOCK_WRITE))
2930099 {
2930100 proc_table[pid].wakeup_events = 0;
2930101 proc_table[pid].status = PROC_READY;
2930102 }
2930103 }
2930104 }
2930105 }
|
|
94.14.8
kernel/proc/proc_sch_signals.c
Si veda la sezione 93.20.7.
2940001 #include <kernel/proc.h>
2940002 //----------------------------------------------------------
2940003 void
2940004 proc_sch_signals (void)
2940005 {
2940006 pid_t pid;
2940007 //
2940008 // The PID scan starts from 1: you will not send
2940009 // signals to the
2940010 // kernel!
2940011 //
2940012 for (pid = 1; pid < PROCESS_MAX; pid++)
2940013 {
2940014 proc_sig_term (pid, SIGHUP);
2940015 proc_sig_term (pid, SIGINT);
2940016 proc_sig_core (pid, SIGQUIT);
2940017 proc_sig_core (pid, SIGILL);
2940018 proc_sig_core (pid, SIGABRT);
2940019 proc_sig_core (pid, SIGFPE);
2940020 proc_sig_term (pid, SIGKILL);
2940021 proc_sig_core (pid, SIGSEGV);
2940022 proc_sig_term (pid, SIGPIPE);
2940023 proc_sig_term (pid, SIGALRM);
2940024 proc_sig_term (pid, SIGTERM);
2940025 proc_sig_term (pid, SIGUSR1);
2940026 proc_sig_term (pid, SIGUSR2);
2940027 proc_sig_chld (pid, SIGCHLD);
2940028 proc_sig_cont (pid, SIGCONT);
2940029 proc_sig_stop (pid, SIGSTOP);
2940030 proc_sig_stop (pid, SIGTSTP);
2940031 proc_sig_stop (pid, SIGTTIN);
2940032 proc_sig_stop (pid, SIGTTOU);
2940033 }
2940034 }
|
|
94.14.9
kernel/proc/proc_sch_terminals.c
Si veda la sezione 93.20.8.
2950001 #include <kernel/proc.h>
2950002 #include <kernel/lib_k.h>
2950003 #include <kernel/lib_s.h>
2950004 #include <kernel/driver/kbd.h>
2950005 #include <termios.h>
2950006 #include <limits.h>
2950007 //----------------------------------------------------------
2950008 void
2950009 proc_sch_terminals (void)
2950010 {
2950011 pid_t pid;
2950012 pid_t pid_sub;
2950013 unsigned char key;
2950014 tty_t *tty;
2950015 dev_t device;
2950016 int k; // Reverse count killed character.
2950017 int overflow = 0; // True if input is too much.
2950018 //
2950019 // Try to read a key from console keyboard buffer
2950020 // (only consoles
2950021 // are available). Variable `kbd' is external and
2950022 // comes from
2950023 // `kernel/kbd.h'.
2950024 //
2950025 key = kbd.key;
2950026 if (key == 0)
2950027 {
2950028 //
2950029 // No key is ready on the keyboard buffer: just
2950030 // return.
2950031 //
2950032 return;
2950033 }
2950034 else
2950035 {
2950036 //
2950037 // A key was pressed and it will be processed.
2950038 // Currently, just remove from the keyboard
2950039 // buffer.
2950040 kbd.key = 0;
2950041 }
2950042 //
2950043 // A key is available. Find the currently active
2950044 // console.
2950045 //
2950046 device = tty_console ((dev_t) 0);
2950047 tty = tty_reference (device);
2950048 if (tty == NULL)
2950049 {
2950050 k_printf
2950051 ("kernel alert: console device "
2950052 "0x%04x not found!\n", device);
2950053 //
2950054 // Will send the typed character to the first
2950055 // terminal!
2950056 //
2950057 tty = tty_reference ((dev_t) 0);
2950058 }
2950059 //
2950060 // Verify if it is a control key that must be
2950061 // handled before
2950062 // entering the canonical input line.
2950063 //
2950064 // Check for a console switch key combination.
2950065 //
2950066 if (key == 0x11) // [Ctrl Q] -> DC1 ->
2950067 // console0.
2950068 {
2950069 tty_console (DEV_CONSOLE0); // Switch.
2950070 return;
2950071 }
2950072 else if (key == 0x12) // [Ctrl R] -> DC2 ->
2950073 // console1.
2950074 {
2950075 tty_console (DEV_CONSOLE1); // Switch.
2950076 return;
2950077 }
2950078 else if (key == 0x13) // [Ctrl S] -> DC3 ->
2950079 // console2.
2950080 {
2950081 tty_console (DEV_CONSOLE2); // Switch.
2950082 return;
2950083 }
2950084 else if (key == 0x14) // [Ctrl T] -> DC4 ->
2950085 // console3.
2950086 {
2950087 tty_console (DEV_CONSOLE3); // Switch.
2950088 return;
2950089 }
2950090 // -------------------------------------------------
2950091 // Only canonical input line is available: ICANON!
2950092 // -------------------------------------------------
2950093 //
2950094 // Might be necessary to send a signal to all
2950095 // processes with the
2950096 // same control terminal, excluded the kernel (0)
2950097 // and `init' (1).
2950098 // Such control keys are not passed to the
2950099 // applications, or are
2950100 // replaced with zero.
2950101 //
2950102 // Please note that this a simplified solution,
2950103 // because the signal
2950104 // should reach only the foreground process of the
2950105 // group. For that
2950106 // reason, only che [Ctrl C] is taken into
2950107 // consideration, because
2950108 // processes can ignore the signal 'SIGINT'.
2950109 //
2950110 if (tty->pgrp != 0)
2950111 {
2950112 //
2950113 // There is a process group for that terminal.
2950114 //
2950115 if (tty->attr.c_cc[VINTR]
2950116 && key == tty->attr.c_cc[VINTR])
2950117 {
2950118 if (tty->attr.c_iflag & IGNBRK)
2950119 {
2950120 //
2950121 // No break!
2950122 //
2950123 return;
2950124 }
2950125 //
2950126 if (tty->attr.c_iflag & BRKINT)
2950127 {
2950128 if (tty->attr.c_lflag & ISIG)
2950129 {
2950130 for (pid = 2; pid < PROCESS_MAX; pid++)
2950131 {
2950132 if (proc_table[pid].pgrp == tty->pgrp)
2950133 {
2950134 //
2950135 // Should find only final
2950136 // process/processes.
2950137 // So, if there is a son
2950138 // process with the
2950139 // same process group, the
2950140 // signal is not
2950141 // sent!
2950142 //
2950143 for (pid_sub = 2;
2950144 pid_sub < PROCESS_MAX;
2950145 pid_sub++)
2950146 {
2950147 if ((proc_table[pid_sub].ppid
2950148 == pid)
2950149 &&
2950150 (proc_table[pid_sub].pgrp
2950151 == tty->pgrp))
2950152 {
2950153 //
2950154 // `pid_sub' is a
2950155 // son of
2950156 // `pid' and is part
2950157 // of the
2950158 // same process
2950159 // group. `pid_sub'
2950160 // is candidate for
2950161 // kill.
2950162 //
2950163 break;
2950164 }
2950165 }
2950166 //
2950167 if (pid_sub >= PROCESS_MAX)
2950168 {
2950169 //
2950170 // There is no son for
2950171 // `pid', sorry.
2950172 //
2950173 s_kill ((pid_t) 0, pid,
2950174 SIGINT);
2950175 //
2950176 // No more scan.
2950177 //
2950178 break;
2950179 }
2950180 }
2950181 }
2950182 }
2950183 //
2950184 // Just reset input line and return.
2950185 //
2950186 tty->status = TTY_INPUT_LINE_EDITING;
2950187 tty->lpr = 0;
2950188 tty->lpw = 0;
2950189 tty->line[0] = 0;
2950190 //
2950191 return;
2950192 }
2950193 //
2950194 // Replace the INTR character with zero.
2950195 //
2950196 key = 0;
2950197 }
2950198 }
2950199 //
2950200 // Check if something is to be ignored.
2950201 //
2950202 if (key == '\r' && (tty->attr.c_iflag & IGNCR))
2950203 {
2950204 return;
2950205 }
2950206 //
2950207 // Check if something is to be replaced, before
2950208 // editing.
2950209 //
2950210 if (key == '\n' && (tty->attr.c_iflag & INLCR))
2950211 {
2950212 key = '\r';
2950213 }
2950214 //
2950215 if (key == '\r' && (tty->attr.c_iflag & ICRNL))
2950216 {
2950217 key = '\n';
2950218 }
2950219 //
2950220 // Edit the canonical input line.
2950221 // Input is accepted only if status is ok.
2950222 //
2950223 if (tty->status == TTY_INPUT_LINE_EDITING)
2950224 {
2950225 //
2950226 // Fix internal line positions.
2950227 //
2950228 if (tty->lpw < 0)
2950229 {
2950230 tty->lpw = 0;
2950231 }
2950232 if (tty->lpw >= MAX_CANON)
2950233 {
2950234 tty->lpw = MAX_CANON - 1;
2950235 overflow = 1; // Too much input!
2950236 }
2950237 if (tty->lpr < 0)
2950238 {
2950239 tty->lpr = 0;
2950240 }
2950241 if (tty->lpr > tty->lpw)
2950242 {
2950243 tty->lpr = tty->lpw;
2950244 }
2950245 //
2950246 // Check input key.
2950247 //
2950248 if (key == '\0')
2950249 {
2950250 //
2950251 // A INTR replaced into zero.
2950252 //
2950253 tty->line[tty->lpw] = key;
2950254 tty->status = TTY_INPUT_LINE_CLOSED;
2950255 proc_wakeup_terminal ();
2950256 }
2950257 else if (key == '\n')
2950258 {
2950259 tty->line[tty->lpw] = key;
2950260 tty->status = TTY_INPUT_LINE_CLOSED;
2950261 proc_wakeup_terminal ();
2950262 }
2950263 else if (tty->attr.c_cc[VEOF]
2950264 && key == tty->attr.c_cc[VEOF])
2950265 {
2950266 //
2950267 // EOF is not included inside the line: just
2950268 // replace the
2950269 // with zero.
2950270 //
2950271 key = 0;
2950272 tty->line[tty->lpw] = key;
2950273 tty->status = TTY_INPUT_LINE_CLOSED;
2950274 proc_wakeup_terminal ();
2950275 }
2950276 else if (tty->attr.c_cc[VEOL]
2950277 && key == tty->attr.c_cc[VEOL])
2950278 {
2950279 tty->line[tty->lpw] = key;
2950280 tty->status = TTY_INPUT_LINE_CLOSED;
2950281 proc_wakeup_terminal ();
2950282 }
2950283 else if (tty->attr.c_cc[VERASE]
2950284 && key == tty->attr.c_cc[VERASE])
2950285 {
2950286 //
2950287 // Save how many characters to be killed, if
2950288 // echo is
2950289 // enabled.
2950290 //
2950291 if (overflow)
2950292 {
2950293 k = tty->lpw + 1;
2950294 //
2950295 // The `tty->lpw' was already reduced.
2950296 //
2950297 }
2950298 else
2950299 {
2950300 k = tty->lpw;
2950301 //
2950302 // Reduce write index: if it is less
2950303 // than zero, it will
2950304 // be fixed.
2950305 //
2950306 tty->lpw--;
2950307 }
2950308 }
2950309 else if (tty->attr.c_cc[VKILL]
2950310 && key == tty->attr.c_cc[VKILL])
2950311 {
2950312 //
2950313 // Save how many characters to be killed, if
2950314 // echo is
2950315 // enabled.
2950316 //
2950317 if (overflow)
2950318 {
2950319 k = tty->lpw + 1;
2950320 }
2950321 else
2950322 {
2950323 k = tty->lpw;
2950324 }
2950325 //
2950326 // Reset input line.
2950327 //
2950328 tty->lpw = 0;
2950329 tty->lpr = 0;
2950330 tty->line[0] = 0;
2950331 }
2950332 else
2950333 {
2950334 tty->line[tty->lpw] = key;
2950335 tty->lpw++;
2950336 }
2950337 //
2950338 // Echo.
2950339 //
2950340 if (!(tty->attr.c_lflag & ECHO))
2950341 {
2950342 //
2950343 // No echo. But NL might be echoed anyway.
2950344 //
2950345 if (key == '\n' && (tty->attr.c_lflag & ECHONL))
2950346 {
2950347 dev_io ((pid_t) 0, tty->device,
2950348 DEV_WRITE, (off_t) 0, &key,
2950349 (size_t) 1, NULL);
2950350 }
2950351 //
2950352 return;
2950353 }
2950354 //
2950355 // The echo is requested.
2950356 //
2950357 if (key == 0)
2950358 {
2950359 //
2950360 // There is nothing to echo.
2950361 //
2950362 ;
2950363 }
2950364 else if (tty->attr.c_cc[VERASE]
2950365 && key == tty->attr.c_cc[VERASE])
2950366 {
2950367 if (tty->attr.c_lflag & ECHOE)
2950368 {
2950369 if (k > 0)
2950370 {
2950371 dev_io ((pid_t) 0, tty->device,
2950372 DEV_WRITE, (off_t) 0,
2950373 "\b \b", (size_t) 3, NULL);
2950374 }
2950375 }
2950376 else
2950377 {
2950378 dev_io ((pid_t) 0, tty->device,
2950379 DEV_WRITE, (off_t) 0, &key,
2950380 (size_t) 1, NULL);
2950381 }
2950382 }
2950383 else if (tty->attr.c_cc[VKILL]
2950384 && key == tty->attr.c_cc[VKILL])
2950385 {
2950386 if (tty->attr.c_lflag & ECHOK)
2950387 {
2950388 for (; k > 0; k--)
2950389 {
2950390 dev_io ((pid_t) 0, tty->device,
2950391 DEV_WRITE, (off_t) 0,
2950392 "\b \b", (size_t) 3, NULL);
2950393 }
2950394 }
2950395 }
2950396 else if (key == '\n')
2950397 {
2950398 if (tty->attr.c_lflag & ECHONL)
2950399 {
2950400 dev_io ((pid_t) 0, tty->device,
2950401 DEV_WRITE, (off_t) 0, &key,
2950402 (size_t) 1, NULL);
2950403 }
2950404 }
2950405 else
2950406 {
2950407 //
2950408 // If there was an overflow, the last
2950409 // character is
2950410 // overwriting the last position, so a back
2950411 // space
2950412 // is printed.
2950413 //
2950414 if (overflow)
2950415 {
2950416 dev_io ((pid_t) 0, tty->device,
2950417 DEV_WRITE, (off_t) 0, "\b",
2950418 (size_t) 1, NULL);
2950419 }
2950420 //
2950421 // Now show the input character.
2950422 //
2950423 dev_io ((pid_t) 0, tty->device, DEV_WRITE,
2950424 (off_t) 0, &key, (size_t) 1, NULL);
2950425 }
2950426 }
2950427 }
|
|
94.14.10
kernel/proc/proc_sch_timers.c
Si veda la sezione 93.20.9.
2960001 #include <kernel/proc.h>
2960002 #include <kernel/lib_k.h>
2960003 #include <kernel/lib_s.h>
2960004 //----------------------------------------------------------
2960005 void
2960006 proc_sch_timers (void)
2960007 {
2960008 static unsigned long long int previous_time;
2960009 unsigned long long int current_time;
2960010 unsigned int pid;
2960011 current_time = s_time ((pid_t) 0, NULL);
2960012 if (previous_time != current_time)
2960013 {
2960014 for (pid = 0; pid < PROCESS_MAX; pid++)
2960015 {
2960016 if ((proc_table[pid].wakeup_events &
2960017 WAKEUP_EVENT_TIMER)
2960018 && (proc_table[pid].status == PROC_SLEEPING)
2960019 && (proc_table[pid].wakeup_timer > 0))
2960020 {
2960021 proc_table[pid].wakeup_timer--;
2960022 if (proc_table[pid].wakeup_timer == 0)
2960023 {
2960024 proc_table[pid].status = PROC_READY;
2960025 }
2960026 }
2960027 }
2960028 }
2960029 previous_time = current_time;
2960030 }
|
|
94.14.11
kernel/proc/proc_scheduler.c
Si veda la sezione 93.20.10.
2970001 #include <kernel/proc.h>
2970002 #include <kernel/lib_k.h>
2970003 #include <kernel/lib_s.h>
2970004 #include <kernel/net.h>
2970005 #include <stdint.h>
2970006 //----------------------------------------------------------
2970007 #define DEBUG 1
2970008 //----------------------------------------------------------
2970009 extern uint32_t _ksp;
2970010 extern uint32_t proc_stack_pointer;
2970011 extern uint16_t proc_stack_segment_selector;
2970012 extern pid_t proc_current;
2970013 //----------------------------------------------------------
2970014 void
2970015 proc_scheduler (void)
2970016 {
2970017 pid_t prev;
2970018 pid_t next;
2970019 addr_t stack_top;
2970020 addr_t stack_bottom;
2970021 uint32_t saved_stack_pointer = proc_stack_pointer;
2970022 //
2970023 static unsigned long long int previous_clock;
2970024 unsigned long long int current_clock;
2970025 //
2970026 // Check the current stack size.
2970027 //
2970028 if (proc_table[proc_current].domain_data == 0)
2970029 {
2970030 stack_bottom = proc_table[proc_current].domain_text;
2970031 }
2970032 else
2970033 {
2970034 stack_bottom = proc_table[proc_current].domain_data;
2970035 }
2970036 //
2970037 stack_top =
2970038 stack_bottom - proc_table[proc_current].domain_stack;
2970039 //
2970040 // Check if the process has broken data with the
2970041 // stack,
2970042 // or if it is near the end of its domain.
2970043 //
2970044 if (proc_stack_pointer <= stack_top)
2970045 {
2970046 //
2970047 // The stack overlaped the other data!
2970048 //
2970049 k_printf
2970050 ("[%s] Kernel alert: the stack of process %i "
2970051 "is grown beyond the allowed space! "
2970052 "The process "
2970053 "is closed. Stack top is %i, "
2970054 "stack pointer is %i.\n",
2970055 __FILE__, (int) proc_current, (int) stack_top,
2970056 (int) proc_stack_pointer);
2970057 //
2970058 // The process is terminated badly.
2970059 //
2970060 s__exit (proc_current, -1);
2970061 }
2970062 else if (proc_stack_pointer < (stack_top + 1024))
2970063 {
2970064 //
2970065 // There is only 1 Kibyte and the stack is
2970066 // finished!
2970067 //
2970068 k_printf
2970069 ("[%s] Kernel alert: the stack of process %i "
2970070 "is near the end of the allowed space! "
2970071 "It remains only %i byte and it will "
2970072 "overwrite other data!\n", __FILE__,
2970073 (int) proc_current,
2970074 (int) (proc_stack_pointer - stack_top));
2970075 }
2970076 //
2970077 // Save previous PID. Variable `proc_current' is
2970078 // extern.
2970079 //
2970080 prev = proc_current;
2970081 //
2970082 // Take care of networking.
2970083 //
2970084 proc_sch_net ();
2970085 //
2970086 // Take care of sleeping processes: wake up if
2970087 // sleeping time
2970088 // elapsed.
2970089 //
2970090 proc_sch_timers ();
2970091 //
2970092 // Take care of pending signals.
2970093 //
2970094 proc_sch_signals ();
2970095 //
2970096 // Take care input from terminals.
2970097 //
2970098 proc_sch_terminals ();
2970099 //
2970100 // Update the CPU time usage.
2970101 //
2970102 current_clock = s_clock ((pid_t) 0);
2970103 proc_table[prev].usage += current_clock - previous_clock;
2970104 previous_clock = current_clock;
2970105 //
2970106 // Check stack pointer changes, made probably by
2970107 // `proc_sig_handler()' called from
2970108 // `proc_sch_signals()'.
2970109 //
2970110 if (DEBUG)
2970111 {
2970112 if (saved_stack_pointer != proc_stack_pointer)
2970113 {
2970114 k_printf
2970115 ("[%s] pid %i, ESP from %i to %i.\n",
2970116 __FILE__, proc_current,
2970117 saved_stack_pointer, proc_stack_pointer);
2970118 }
2970119 }
2970120 //
2970121 // Scan for a next process.
2970122 //
2970123 for (next = prev + 1; next != prev; next++)
2970124 {
2970125 if (next >= PROCESS_MAX)
2970126 {
2970127 next = -1; // At the next loop, `next'
2970128 // will be zero.
2970129 continue;
2970130 }
2970131 //
2970132 if (proc_table[next].status == PROC_EMPTY)
2970133 {
2970134 continue;
2970135 }
2970136 else if (proc_table[next].status == PROC_CREATED)
2970137 {
2970138 continue;
2970139 }
2970140 else if (proc_table[next].status == PROC_READY)
2970141 {
2970142 if (proc_table[prev].status == PROC_RUNNING)
2970143 {
2970144 proc_table[prev].status = PROC_READY;
2970145 }
2970146 //
2970147 proc_table[prev].sp = proc_stack_pointer;
2970148 proc_table[next].status = PROC_RUNNING;
2970149 proc_table[next].ret = 0;
2970150 //
2970151 proc_current = next;
2970152 proc_stack_segment_selector
2970153 = gdt_pid_to_segment_data (next) * 8;
2970154 proc_stack_pointer = proc_table[next].sp;
2970155 break;
2970156 }
2970157 else if (proc_table[next].status == PROC_RUNNING)
2970158 {
2970159 if (proc_table[prev].status == PROC_RUNNING)
2970160 {
2970161 k_printf ("Kernel alert: process %i "
2970162 "and %i \"running\"!\n",
2970163 prev, next);
2970164 proc_table[prev].status = PROC_READY;
2970165 }
2970166 //
2970167 proc_table[prev].sp = proc_stack_pointer;
2970168 proc_table[next].status = PROC_RUNNING;
2970169 proc_table[next].ret = 0;
2970170 //
2970171 proc_current = next;
2970172 proc_stack_segment_selector
2970173 = gdt_pid_to_segment_data (next) * 8;
2970174 proc_stack_pointer = proc_table[next].sp;
2970175 break;
2970176 }
2970177 else if (proc_table[next].status == PROC_SLEEPING)
2970178 {
2970179 continue;
2970180 }
2970181 else if (proc_table[next].status == PROC_ZOMBIE)
2970182 {
2970183 continue;
2970184 }
2970185 }
2970186 //
2970187 // Check again if the next process is set to
2970188 // running, otherwise set
2970189 // the kernel to such value!
2970190 //
2970191 if (proc_table[next].status != PROC_RUNNING)
2970192 {
2970193 proc_table[0].status = PROC_RUNNING;
2970194 proc_current = 0;
2970195 proc_stack_segment_selector
2970196 = gdt_pid_to_segment_data (0) * 8;
2970197 proc_stack_pointer = proc_table[0].sp;
2970198 }
2970199 //
2970200 // Save kernel stack pointer.
2970201 //
2970202 _ksp = proc_table[0].sp;
2970203 }
|
|
94.14.12
kernel/proc/proc_sig_chld.c
Si veda la sezione 93.20.11.
2980001 #include <kernel/proc.h>
2980002 //----------------------------------------------------------
2980003 // At the moment, the SIGCHLD is handled only per
2980004 // default: no other handler is taken into
2980005 // consideration.
2980006 //----------------------------------------------------------
2980007 void
2980008 proc_sig_chld (pid_t parent, int sig)
2980009 {
2980010 pid_t child;
2980011 //
2980012 // Please note that `sig' should be SIGCHLD and
2980013 // nothing else.
2980014 // So, the following test, means to verify if the
2980015 // parent process
2980016 // has received a SIGCHLD already.
2980017 //
2980018 if (proc_sig_status (parent, sig))
2980019 {
2980020 if ((!proc_sig_ignore (parent, sig))
2980021 && (proc_table[parent].status ==
2980022 PROC_SLEEPING)
2980023 && (proc_table[parent].wakeup_events &
2980024 WAKEUP_EVENT_SIGNAL)
2980025 && (proc_table[parent].wakeup_signal == sig))
2980026 {
2980027 //
2980028 // The signal is not ignored from the parent
2980029 // process;
2980030 // the parent process is sleeping;
2980031 // the parent process is waiting for a
2980032 // signal;
2980033 // the parent process is waiting for current
2980034 // signal.
2980035 // So, just wake it up.
2980036 //
2980037 proc_table[parent].status = PROC_READY;
2980038 proc_table[parent].wakeup_events = 0;
2980039 proc_table[parent].wakeup_signal = 0;
2980040 }
2980041 else
2980042 {
2980043 //
2980044 // All other cases, means to remove all dead
2980045 // children.
2980046 //
2980047 for (child = 1; child < PROCESS_MAX; child++)
2980048 {
2980049 if (proc_table[child].ppid == parent
2980050 && proc_table[child].status ==
2980051 PROC_ZOMBIE)
2980052 {
2980053 proc_available (child);
2980054 }
2980055 }
2980056 }
2980057 proc_sig_off (parent, sig);
2980058 }
2980059 }
|
|
94.14.13
kernel/proc/proc_sig_cont.c
Si veda la sezione 93.20.12.
2990001 #include <kernel/proc.h>
2990002 //----------------------------------------------------------
2990003 void
2990004 proc_sig_cont (pid_t pid, int sig)
2990005 {
2990006 //
2990007 // The value for argument `sig' should be SIGCONT.
2990008 //
2990009 if (proc_sig_status (pid, sig))
2990010 {
2990011 if (proc_sig_ignore (pid, sig))
2990012 {
2990013 proc_sig_off (pid, sig);
2990014 }
2990015 else
2990016 {
2990017 if (proc_table[pid].sig_handler[sig] !=
2990018 (uintptr_t) NULL)
2990019 {
2990020 proc_sig_handler (pid, sig);
2990021 }
2990022 else
2990023 {
2990024 proc_table[pid].status = PROC_READY;
2990025 proc_sig_off (pid, sig);
2990026 }
2990027 }
2990028 }
2990029 }
|
|
94.14.14
kernel/proc/proc_sig_core.c
Si veda la sezione 93.20.13.
3000001 #include <kernel/proc.h>
3000002 #include <kernel/lib_s.h>
3000003 //----------------------------------------------------------
3000004 void
3000005 proc_sig_core (pid_t pid, int sig)
3000006 {
3000007 addr_t address_text;
3000008 addr_t address_data;
3000009 size_t domain_text;
3000010 size_t domain_data;
3000011 size_t extra_data;
3000012 //
3000013 if (proc_sig_status (pid, sig))
3000014 {
3000015 if (proc_sig_ignore (pid, sig))
3000016 {
3000017 proc_sig_off (pid, sig);
3000018 }
3000019 else
3000020 {
3000021 if (proc_table[pid].sig_handler[sig] !=
3000022 (uintptr_t) NULL)
3000023 {
3000024 proc_sig_handler (pid, sig);
3000025 }
3000026 else
3000027 {
3000028 //
3000029 // Save process addresses and sizes
3000030 // (might be useful if
3000031 // we want to try to exit the process
3000032 // before core dump.
3000033 //
3000034 address_text = proc_table[pid].address_text;
3000035 address_data = proc_table[pid].address_data;
3000036 domain_text = proc_table[pid].domain_text;
3000037 domain_data = proc_table[pid].domain_data;
3000038 extra_data = proc_table[pid].extra_data;
3000039 //
3000040 // Core dump: the process who formally
3000041 // writes the file
3000042 // is the terminating one.
3000043 //
3000044 if (domain_data == 0)
3000045 {
3000046 proc_dump_memory (pid, address_text,
3000047 domain_text +
3000048 extra_data, "core");
3000049 }
3000050 else
3000051 {
3000052 proc_dump_memory (pid, address_text,
3000053 domain_text,
3000054 "core.text");
3000055 proc_dump_memory (pid, address_data,
3000056 domain_data +
3000057 extra_data,
3000058 "core.data");
3000059 }
3000060 //
3000061 // The signal, translated to negative,
3000062 // is returned (but
3000063 // the effective value received by the
3000064 // application will
3000065 // be cutted, leaving only the low 8
3000066 // bit).
3000067 //
3000068 s__exit (pid, -sig);
3000069 }
3000070 }
3000071 }
3000072 }
|
|
94.14.15
kernel/proc/proc_sig_handler.c
Si veda la sezione 93.20.14.
3010001 #include <kernel/proc.h>
3010002 #include <kernel/lib_s.h>
3010003 #include <kernel/lib_k.h>
3010004 #include <stdint.h>
3010005 //----------------------------------------------------------
3010006 #define DEBUG 0
3010007 //----------------------------------------------------------
3010008 void
3010009 proc_sig_handler (pid_t pid, int sig)
3010010 {
3010011 addr_t addr_data_top;
3010012 addr_t addr_stack_pointer;
3010013 uint32_t old_eip;
3010014 uint32_t old_cs;
3010015 uint32_t old_eflags;
3010016 //
3010017 // Stack frames.
3010018 //
3010019 struct
3010020 {
3010021 uint32_t eax;
3010022 uint32_t ecx;
3010023 uint32_t edx;
3010024 uint32_t ebx;
3010025 uint32_t ebp;
3010026 uint32_t esi;
3010027 uint32_t edi;
3010028 uint32_t ds;
3010029 uint32_t es;
3010030 uint32_t fs;
3010031 uint32_t gs;
3010032 uint32_t eip;
3010033 uint32_t cs;
3010034 uint32_t eflags;
3010035 } *old;
3010036 //
3010037 struct
3010038 {
3010039 uint32_t eax;
3010040 uint32_t ecx;
3010041 uint32_t edx;
3010042 uint32_t ebx;
3010043 uint32_t ebp;
3010044 uint32_t esi;
3010045 uint32_t edi;
3010046 uint32_t ds;
3010047 uint32_t es;
3010048 uint32_t fs;
3010049 uint32_t gs;
3010050 uint32_t wrapper;
3010051 uint32_t cs;
3010052 uint32_t eflags;
3010053 uint32_t handler;
3010054 uint32_t signal;
3010055 uint32_t eip;
3010056 } *new;
3010057 //
3010058 // First of all, this function can act only for a
3010059 // process that
3010060 // is not *just* interrupted. That is, if
3010061 // `proc_current' is
3010062 // equal to `pid', nothing is to be done yet: it
3010063 // will be done
3010064 // only when it will be in pause.
3010065 //
3010066 if (pid == proc_current)
3010067 {
3010068 //
3010069 // Nothing to do yet.
3010070 //
3010071 return;
3010072 }
3010073 //
3010074 // Check if there is a function to run.
3010075 //
3010076 if (proc_table[pid].sig_handler[sig] == (uintptr_t) NULL)
3010077 {
3010078 //
3010079 // Nothing to do.
3010080 //
3010081 return;
3010082 }
3010083 //
3010084 // Tell something for debugging.
3010085 //
3010086 if (DEBUG)
3010087 {
3010088 k_printf ("%s(%i, %i)", __func__, (int) pid, sig);
3010089 }
3010090 //
3010091 // Calculate the absolute stack section address,
3010092 // from the
3010093 // kernel point of view.
3010094 //
3010095 if (proc_table[pid].domain_data == 0)
3010096 {
3010097 addr_data_top = proc_table[pid].address_text;
3010098 }
3010099 else
3010100 {
3010101 addr_data_top = proc_table[pid].address_data;
3010102 }
3010103 //
3010104 // Then calculate the effective stack pointer
3010105 // address.
3010106 // We are considering only process that are not
3010107 // currently interrupted, so the stack pointer is
3010108 // taken from `proc_table[pid].sp'.
3010109 //
3010110 addr_stack_pointer = addr_data_top + proc_table[pid].sp;
3010111 //
3010112 // Currently the process stack is as it follows.
3010113 // The address inside `addr_stack_pointer' is
3010114 // corresponding
3010115 // to the saved EAX value.
3010116 //
3010117 // pushl %eflags #
3010118 // pushl %cs # from the interrupt
3010119 // pushl %eip #
3010120 // -------------
3010121 // pushl %gs
3010122 // pushl %fs
3010123 // pushl %es
3010124 // pushl %ds
3010125 // pushl %edi
3010126 // pushl %esi
3010127 // pushl %ebp
3010128 // pushl %ebx
3010129 // pushl %edx
3010130 // pushl %ecx
3010131 // pushl %eax
3010132 //
3010133 // Need to insert the call to the handler function.
3010134 // The process stack should become this way:
3010135 //
3010136 // pushl %eip [0]
3010137 // pushl <signal> [1]
3010138 // pushl <handler> [1]
3010139 // pushl %eflags [2]
3010140 // pushl %cs [2]
3010141 // pushl <wrapper> [2]
3010142 // -------------
3010143 // pushl %gs
3010144 // pushl %fs
3010145 // pushl %es
3010146 // pushl %ds
3010147 // pushl %edi
3010148 // pushl %esi
3010149 // pushl %ebp
3010150 // pushl %ebx
3010151 // pushl %edx
3010152 // pushl %ecx
3010153 // pushl %eax
3010154 //
3010155 // [0] Back from the original interrupt.
3010156 //
3010157 // [1] Arguments of the wrapper functions, that will
3010158 // call the
3010159 // signal handler, and then will return to the
3010160 // address at
3010161 // [1].
3010162 //
3010163 // [2] Modified so that the IRET instruction will
3010164 // return
3010165 // to the begin of the wrapper function, that will
3010166 // call the true signal handler, and will return
3010167 // at [1].
3010168 //
3010169 // Now set the pointer to the old and new frame,
3010170 // updating the stack pointer address.
3010171 //
3010172 old = (void *) addr_stack_pointer;
3010173 addr_stack_pointer -= 12; // Three more
3010174 // elements.
3010175 new = (void *) addr_stack_pointer;
3010176 //
3010177 // Verify if the code segment was correctly found.
3010178 //
3010179 if (DEBUG)
3010180 {
3010181 k_printf
3010182 ("[%s] EAX:%04x ECX:%04x EDX:%04x "
3010183 "EBX:%04x EBP:%04x "
3010184 "ESI:%04x EDI:%04x DS:%04x ES:%04x "
3010185 "FS:%04x GS:%04x "
3010186 "EIP:%04x CS:%04x EFLAGS:%04x\n", __FILE__,
3010187 (int) old->eax, (int) old->ecx,
3010188 (int) old->edx, (int) old->ebx,
3010189 (int) old->ebp, (int) old->esi,
3010190 (int) old->edi, (int) old->ds, (int) old->es,
3010191 (int) old->fs, (int) old->gs, (int) old->eip,
3010192 (int) old->cs, (int) old->eflags);
3010193 }
3010194 //
3010195 // Move data, to arrange the new stack. The order
3010196 // does
3010197 // matter, as the new frame overwrites the old one.
3010198 //
3010199 new->eax = old->eax;
3010200 new->ecx = old->ecx;
3010201 new->edx = old->edx;
3010202 new->ebx = old->ebx;
3010203 new->ebp = old->ebp;
3010204 new->esi = old->esi;
3010205 new->edi = old->edi;
3010206 new->ds = old->ds;
3010207 new->es = old->es;
3010208 new->fs = old->fs;
3010209 new->gs = old->gs;
3010210 //
3010211 old_eflags = old->eflags;
3010212 old_cs = old->cs;
3010213 old_eip = old->eip;
3010214 //
3010215 new->wrapper = proc_table[pid].sig_handler_wrapper;
3010216 new->cs = old_cs;
3010217 new->eflags = old_eflags;
3010218 new->handler = proc_table[pid].sig_handler[sig];
3010219 new->signal = sig;
3010220 new->eip = old_eip;
3010221 //
3010222 // Tell what is changed inside the stack.
3010223 //
3010224 if (DEBUG)
3010225 {
3010226 k_printf
3010227 ("[%s] EAX:%04x ECX:%04x EDX:%04x "
3010228 "EBX:%04x EBP:%04x "
3010229 "ESI:%04x EDI:%04x DS:%04x ES:%04x "
3010230 "FS:%04x GS:%04x "
3010231 "wrapper:%04x CS:%04x EFLAGS:%04x "
3010232 "handler:%04x "
3010233 "signal:$04x EIP:%04x\n", __FILE__,
3010234 (int) new->eax, (int) new->ecx,
3010235 (int) new->edx, (int) new->ebx,
3010236 (int) new->ebp, (int) new->esi,
3010237 (int) new->edi, (int) new->ds, (int) new->es,
3010238 (int) new->fs, (int) new->gs,
3010239 (int) new->wrapper, (int) new->cs,
3010240 (int) new->eflags, (int) new->handler,
3010241 (int) new->signal, (int) new->eip);
3010242 }
3010243 //
3010244 // Change the stack pointer of the process, as it
3010245 // was increased.
3010246 //
3010247 proc_table[pid].sp = addr_stack_pointer - addr_data_top;
3010248 //
3010249 // Reset the signal handler, as in traditional Unix,
3010250 // with
3010251 // all the consequences that such implementation
3010252 // will give.
3010253 //
3010254 proc_table[pid].sig_handler[sig] = (uintptr_t) NULL;
3010255 proc_sig_off (pid, sig);
3010256 //
3010257 // Wake up the process if it is sleeping.
3010258 //
3010259 proc_table[pid].wakeup_events = 0;
3010260 proc_table[pid].status = PROC_READY;
3010261 }
|
|
94.14.16
kernel/proc/proc_sig_ignore.c
Si veda la sezione 93.20.15.
3020001 #include <kernel/proc.h>
3020002 //----------------------------------------------------------
3020003 int
3020004 proc_sig_ignore (pid_t pid, int sig)
3020005 {
3020006 unsigned long int flag = 1L << (sig - 1);
3020007 if (proc_table[pid].sig_ignore & flag)
3020008 {
3020009 return (1);
3020010 }
3020011 else
3020012 {
3020013 return (0);
3020014 }
3020015 }
|
|
94.14.17
kernel/proc/proc_sig_off.c
Si veda la sezione 93.20.17.
3030001 #include <kernel/proc.h>
3030002 //----------------------------------------------------------
3030003 void
3030004 proc_sig_off (pid_t pid, int sig)
3030005 {
3030006 unsigned long int flag = 1L << (sig - 1);
3030007 proc_table[pid].sig_status ^= flag;
3030008 }
|
|
94.14.18
kernel/proc/proc_sig_on.c
Si veda la sezione 93.20.17.
3040001 #include <kernel/proc.h>
3040002 //----------------------------------------------------------
3040003 void
3040004 proc_sig_on (pid_t pid, int sig)
3040005 {
3040006 unsigned long int flag = 1L << (sig - 1);
3040007 proc_table[pid].sig_status |= flag;
3040008 }
|
|
94.14.19
kernel/proc/proc_sig_status.c
Si veda la sezione 93.20.18.
3050001 #include <kernel/proc.h>
3050002 //----------------------------------------------------------
3050003 int
3050004 proc_sig_status (pid_t pid, int sig)
3050005 {
3050006 unsigned long int flag = 1L << (sig - 1);
3050007 if (proc_table[pid].sig_status & flag)
3050008 {
3050009 return (1);
3050010 }
3050011 else
3050012 {
3050013 return (0);
3050014 }
3050015 }
|
|
94.14.20
kernel/proc/proc_sig_stop.c
Si veda la sezione 93.20.19.
3060001 #include <kernel/proc.h>
3060002 //----------------------------------------------------------
3060003 void
3060004 proc_sig_stop (pid_t pid, int sig)
3060005 {
3060006 if (proc_sig_status (pid, sig))
3060007 {
3060008 if (proc_sig_ignore (pid, sig) && !(sig == SIGSTOP))
3060009 {
3060010 proc_sig_off (pid, sig);
3060011 }
3060012 else
3060013 {
3060014 if ((proc_table[pid].sig_handler[sig] !=
3060015 (uintptr_t) NULL) && (sig != SIGSTOP))
3060016 {
3060017 proc_sig_handler (pid, sig);
3060018 }
3060019 else
3060020 {
3060021 proc_table[pid].status = PROC_SLEEPING;
3060022 proc_table[pid].ret = -sig;
3060023 proc_sig_off (pid, sig);
3060024 }
3060025 }
3060026 }
3060027 }
|
|
94.14.21
kernel/proc/proc_sig_term.c
Si veda la sezione 93.20.20.
3070001 #include <kernel/proc.h>
3070002 #include <kernel/lib_s.h>
3070003 #include <kernel/lib_k.h>
3070004 //----------------------------------------------------------
3070005 void
3070006 proc_sig_term (pid_t pid, int sig)
3070007 {
3070008 if (proc_sig_status (pid, sig))
3070009 {
3070010 if (proc_sig_ignore (pid, sig) && !(sig == SIGKILL))
3070011 {
3070012 proc_sig_off (pid, sig);
3070013 }
3070014 else
3070015 {
3070016 if ((proc_table[pid].sig_handler[sig] !=
3070017 (uintptr_t) NULL) && (sig != SIGKILL))
3070018 {
3070019 proc_sig_handler (pid, sig);
3070020 }
3070021 else
3070022 {
3070023 //
3070024 // The signal, translated to negative,
3070025 // is returned (but
3070026 // the effective value received by the
3070027 // application will
3070028 // be cutted, leaving only the low 8
3070029 // bit).
3070030 //
3070031 s__exit (pid, -sig);
3070032 }
3070033 }
3070034 }
3070035 }
|
|
94.14.22
kernel/proc/proc_sys_exec.c
Si veda la sezione 93.20.21.
3080001 #include <kernel/ibm_i386.h>
3080002 #include <kernel/proc.h>
3080003 #include <errno.h>
3080004 #include <fcntl.h>
3080005 #include <kernel/lib_s.h>
3080006 #include <kernel/lib_k.h>
3080007 //----------------------------------------------------------
3080008 #define DEBUG 0
3080009 //----------------------------------------------------------
3080010 int
3080011 proc_sys_exec (pid_t pid, const char *path,
3080012 unsigned int argc, char *arg_data,
3080013 unsigned int envc, char *env_data)
3080014 {
3080015 unsigned int i;
3080016 unsigned int j;
3080017 char *arg;
3080018 char *env;
3080019 char *envp[ARG_MAX / 16];
3080020 char *argv[ARG_MAX / 16];
3080021 size_t size;
3080022 size_t arg_data_size;
3080023 size_t env_data_size;
3080024 unsigned int p_off;
3080025 inode_t *inode;
3080026 ssize_t size_read;
3080027 header_t header;
3080028 uint32_t new_sp;
3080029 uint32_t envp_address;
3080030 uint32_t argv_address;
3080031 addr_t allocated_text;
3080032 addr_t allocated_data;
3080033 addr_t stack_location; // real stack
3080034 // location.
3080035 size_t process_domain_text;
3080036 size_t process_domain_data;
3080037 size_t process_domain_stack;
3080038 addr_t previous_address_text;
3080039 addr_t previous_address_data;
3080040 size_t previous_domain_text;
3080041 size_t previous_domain_data;
3080042 size_t previous_domain_stack;
3080043 size_t previous_extra_data;
3080044 uint32_t segment_text; // Segment descriptors
3080045 uint32_t segment_data; // inside 32 bit int.
3080046 char buffer[MEM_BLOCK_SIZE];
3080047 uint32_t stack_element;
3080048 off_t off_inode;
3080049 addr_t memory_start;
3080050 int status;
3080051 pid_t extra;
3080052 int proc_count;
3080053 file_t *file;
3080054 int fdn;
3080055 dev_t device;
3080056 int eof;
3080057 int sig;
3080058 //
3080059 // Check for limits.
3080060 //
3080061 if (argc > (ARG_MAX / 16) || envc > (ARG_MAX / 16))
3080062 {
3080063 errset (ENOMEM);
3080064 return (-1);
3080065 }
3080066 //
3080067 // Scan arguments to calculate the full size and the
3080068 // relative
3080069 // pointers. The final size is rounded to 4, for the
3080070 // stack.
3080071 //
3080072 arg = arg_data;
3080073 for (i = 0, j = 0; i < argc; i++)
3080074 {
3080075 argv[i] = (char *) j; // Relative pointer
3080076 // inside the
3080077 // `arg_data'.
3080078 size = strlen (arg);
3080079 arg += size + 1;
3080080 j += size + 1;
3080081 }
3080082 arg_data_size = j;
3080083 if (arg_data_size % 2)
3080084 {
3080085 arg_data_size++;
3080086 }
3080087 if (arg_data_size % 4)
3080088 {
3080089 arg_data_size += 2;
3080090 }
3080091 //
3080092 // Scan environment variables to calculate the full
3080093 // size and the
3080094 // relative pointers. The final size is rounded to
3080095 // 4, for the stack.
3080096 //
3080097 env = env_data;
3080098 for (i = 0, j = 0; i < envc; i++)
3080099 {
3080100 envp[i] = (char *) j; // Relative pointer
3080101 // inside the
3080102 // `env_data'.
3080103 size = strlen (env);
3080104 env += size + 1;
3080105 j += size + 1;
3080106 }
3080107 env_data_size = j;
3080108 if (env_data_size % 2)
3080109 {
3080110 env_data_size++;
3080111 }
3080112 if (env_data_size % 4)
3080113 {
3080114 env_data_size += 2;
3080115 }
3080116 //
3080117 // Read the inode related to the executable file
3080118 // name.
3080119 // Function path_inode() includes the inode get
3080120 // procedure.
3080121 //
3080122 inode = path_inode (pid, path);
3080123 if (inode == NULL)
3080124 {
3080125 errset (ENOENT); // No such file or directory.
3080126 return (-1);
3080127 }
3080128 //
3080129 // Check for permissions.
3080130 //
3080131 status =
3080132 inode_check (inode, S_IFREG, 5,
3080133 proc_table[pid].euid,
3080134 proc_table[pid].egid);
3080135 if (status != 0)
3080136 {
3080137 //
3080138 // File is not of a valid type or permission are
3080139 // not
3080140 // sufficient: release the executable file inode
3080141 // and return with an error.
3080142 //
3080143 inode_put (inode);
3080144 errset (EACCES); // Permission denied.
3080145 return (-1);
3080146 }
3080147 //
3080148 // Read the header from the executable file.
3080149 //
3080150 size_read =
3080151 inode_file_read (inode, (off_t) 0, &header,
3080152 (sizeof header), &eof);
3080153 if (size_read != (sizeof header))
3080154 {
3080155 //
3080156 // The file is shorter than the executable
3080157 // header, so, it isn't
3080158 // an executable: release the file inode and
3080159 // return with an
3080160 // error.
3080161 //
3080162 inode_put (inode);
3080163 errset (ENOEXEC);
3080164 return (-1);
3080165 }
3080166 //
3080167 // Size read is ok.
3080168 //
3080169 if (header.magic != MAGIC_OS32_APPL)
3080170 {
3080171 //
3080172 // The header does not have the expected magic
3080173 // numbers, so,
3080174 // it isn't a valid executable: release the file
3080175 // inode and
3080176 // return with an error.
3080177 //
3080178 inode_put (inode);
3080179 errset (ENOEXEC);
3080180 return (-1); // This is not a valid
3080181 // executable!
3080182 }
3080183 //
3080184 // Calculate code size.
3080185 //
3080186 if (header.data_offset == 0)
3080187 {
3080188 process_domain_text = header.ebss + header.ssize;
3080189 }
3080190 else
3080191 {
3080192 process_domain_text = header.data_offset;
3080193 }
3080194 //
3080195 if (process_domain_text % 4096)
3080196 {
3080197 process_domain_text =
3080198 (((process_domain_text / 4096) + 1) * 4096);
3080199 }
3080200 //
3080201 // Calculate data size, including stack, that cannot
3080202 // stay alone!
3080203 //
3080204 process_domain_stack = header.ssize;
3080205 //
3080206 if (header.data_offset == 0)
3080207 {
3080208 process_domain_data = 0;
3080209 }
3080210 else
3080211 {
3080212 process_domain_data = (header.ebss + header.ssize);
3080213 }
3080214 //
3080215 if (process_domain_data % 4096)
3080216 {
3080217 process_domain_data =
3080218 (((process_domain_data / 4096) + 1) * 4096);
3080219 }
3080220 //
3080221 // Place the new stack pointer to the bottom of the
3080222 // data area:
3080223 // the stack pointer is relative to the data area,
3080224 // so the last
3080225 // relative position is equal to the size.
3080226 //
3080227 if (header.data_offset == 0)
3080228 {
3080229 new_sp = process_domain_text;
3080230 }
3080231 else
3080232 {
3080233 new_sp = process_domain_data;
3080234 }
3080235 //
3080236 // Allocate memory: code and data.
3080237 //
3080238 allocated_text = mb_alloc_size (process_domain_text);
3080239 //
3080240 if (allocated_text == 0)
3080241 {
3080242 //
3080243 // The program instructions (code segment)
3080244 // cannot be loaded
3080245 // into memory: release the executable file
3080246 // inode and return
3080247 // with an error.
3080248 //
3080249 inode_put (inode);
3080250 errset (ENOMEM); // Not enough space.
3080251 return (-1);
3080252 }
3080253 else if (DEBUG)
3080254 {
3080255 k_printf ("%s:%i:mb_alloc_size(%zi)", __FILE__,
3080256 __LINE__,
3080257 (unsigned int) process_domain_text);
3080258 }
3080259 //
3080260 //
3080261 //
3080262 if (header.data_offset == 0)
3080263 {
3080264 //
3080265 // Code and data segments are the same: no need
3080266 // to allocate more memory for the data segment.
3080267 //
3080268 allocated_data = 0;
3080269 process_domain_data = 0;
3080270 }
3080271 else
3080272 {
3080273 //
3080274 // Code and data segments are different: the
3080275 // data
3080276 // segment memory is allocated.
3080277 //
3080278 allocated_data = mb_alloc_size (process_domain_data);
3080279 if (allocated_data == 0)
3080280 {
3080281 //
3080282 // The separated program data (data segment)
3080283 // cannot be
3080284 // loaded into memory: free the already
3080285 // allocated memory
3080286 // for the program instructions, release the
3080287 // executable
3080288 // file inode and return with an error.
3080289 //
3080290 mb_free (allocated_text, process_domain_text);
3080291 if (DEBUG)
3080292 {
3080293 k_printf ("%s:%i:mb_free(%i, %zi)",
3080294 __FILE__, __LINE__,
3080295 (unsigned int) allocated_text,
3080296 process_domain_data);
3080297 }
3080298 inode_put (inode);
3080299 errset (ENOMEM); // Not enough space.
3080300 return (-1);
3080301 }
3080302 else if (DEBUG)
3080303 {
3080304 k_printf ("%s:%i:mb_alloc_size(%zi)",
3080305 __FILE__, __LINE__,
3080306 process_domain_data);
3080307 }
3080308 }
3080309 //
3080310 // Load executable in memory.
3080311 //
3080312 if (header.data_offset == 0)
3080313 {
3080314 //
3080315 // Code and data share the same segment.
3080316 //
3080317 for (eof = 0, memory_start = allocated_text,
3080318 off_inode = 0, size_read = 0;
3080319 off_inode < inode->size && !eof;
3080320 off_inode += size_read)
3080321 {
3080322 memory_start += size_read;
3080323 //
3080324 // Read a block of memory.
3080325 //
3080326 size_read =
3080327 inode_file_read (inode, off_inode, buffer,
3080328 MEM_BLOCK_SIZE, &eof);
3080329 if (size_read < 0)
3080330 {
3080331 //
3080332 // Free memory and inode.
3080333 //
3080334 mb_free (allocated_text, process_domain_text);
3080335 if (DEBUG)
3080336 {
3080337 k_printf ("%s:%i:mb_free(%i, %zi)",
3080338 __FILE__, __LINE__,
3080339 (unsigned int)
3080340 allocated_text,
3080341 process_domain_text);
3080342 }
3080343 inode_put (inode);
3080344 errset (EIO);
3080345 return (-1);
3080346 }
3080347 //
3080348 // Copy inside the right position to be
3080349 // executed.
3080350 //
3080351 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080352 memory_start, buffer,
3080353 (size_t) size_read, NULL);
3080354 }
3080355 }
3080356 else
3080357 {
3080358 //
3080359 // Code and data with different segments.
3080360 //
3080361 for (eof = 0, memory_start = allocated_text,
3080362 off_inode = 0, size_read = 0;
3080363 off_inode < process_domain_text && !eof;
3080364 off_inode += size_read)
3080365 {
3080366 memory_start += size_read;
3080367 //
3080368 // Read a block of memory
3080369 //
3080370 size_read =
3080371 inode_file_read (inode, off_inode, buffer,
3080372 MEM_BLOCK_SIZE, &eof);
3080373 if (size_read < 0)
3080374 {
3080375 //
3080376 // Free memory and inode.
3080377 //
3080378 mb_free (allocated_text, process_domain_text);
3080379 if (DEBUG)
3080380 {
3080381 k_printf ("%s:%i:mb_free(%i, %zi)",
3080382 __FILE__, __LINE__,
3080383 (unsigned int)
3080384 allocated_text,
3080385 process_domain_text);
3080386 }
3080387 mb_free (allocated_data, process_domain_data);
3080388 if (DEBUG)
3080389 {
3080390 k_printf ("%s:%i:mb_free(%i, %zi)",
3080391 __FILE__, __LINE__,
3080392 (unsigned int)
3080393 allocated_data,
3080394 process_domain_data);
3080395 }
3080396 inode_put (inode);
3080397 errset (EIO);
3080398 return (-1);
3080399 }
3080400 //
3080401 // Copy inside the right position to be
3080402 // executed.
3080403 //
3080404 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080405 memory_start, buffer,
3080406 (size_t) size_read, NULL);
3080407 }
3080408 for (eof = 0, memory_start = allocated_data,
3080409 off_inode = header.data_offset, size_read =
3080410 0; off_inode < inode->size && !eof;
3080411 off_inode += size_read)
3080412 {
3080413 memory_start += size_read;
3080414 //
3080415 // Read a block of memory
3080416 //
3080417 size_read =
3080418 inode_file_read (inode, off_inode, buffer,
3080419 MEM_BLOCK_SIZE, &eof);
3080420 if (size_read < 0)
3080421 {
3080422 //
3080423 // Free memory and inode.
3080424 //
3080425 mb_free (allocated_text, process_domain_text);
3080426 if (DEBUG)
3080427 {
3080428 k_printf ("%s:%i:mb_free(%i, %zi)",
3080429 __FILE__, __LINE__,
3080430 (unsigned int)
3080431 allocated_text,
3080432 process_domain_text);
3080433 }
3080434 mb_free (allocated_data, process_domain_data);
3080435 if (DEBUG)
3080436 {
3080437 k_printf ("%s:%i:mb_free(%i, %zi)",
3080438 __FILE__, __LINE__,
3080439 (unsigned int)
3080440 allocated_data,
3080441 process_domain_data);
3080442 }
3080443 inode_put (inode);
3080444 errset (EIO);
3080445 return (-1);
3080446 }
3080447 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080448 memory_start, buffer,
3080449 (size_t) size_read, NULL);
3080450 }
3080451 }
3080452 //
3080453 // The executable file was successfully loaded in
3080454 // memory:
3080455 // release the executable file inode.
3080456 //
3080457 inode_put (inode);
3080458 //
3080459 // Update process TEXT segment inside the GDT table.
3080460 //
3080461 gdt_segment (gdt_pid_to_segment_text (pid),
3080462 (uint32_t) allocated_text,
3080463 (uint32_t) (process_domain_text / 4096),
3080464 1, 1, 0);
3080465 //
3080466 // Update process DATA segment inside the GDT table.
3080467 //
3080468 if (process_domain_data > 0)
3080469 {
3080470 gdt_segment (gdt_pid_to_segment_data (pid),
3080471 (uint32_t) allocated_data,
3080472 (uint32_t) (process_domain_data /
3080473 4096), 1, 0, 0);
3080474 }
3080475 else
3080476 {
3080477 gdt_segment (gdt_pid_to_segment_data (pid),
3080478 (uint32_t) allocated_text,
3080479 (uint32_t) (process_domain_text /
3080480 4096), 1, 0, 0);
3080481 }
3080482 //
3080483 // Calculate segment descriptors.
3080484 //
3080485 segment_text = (gdt_pid_to_segment_text (pid) << 3) + 0;
3080486 segment_data = (gdt_pid_to_segment_data (pid) << 3) + 0;
3080487 //
3080488 // Where is the stack?
3080489 //
3080490 if (process_domain_data > 0)
3080491 {
3080492 stack_location = allocated_data;
3080493 }
3080494 else
3080495 {
3080496 stack_location = allocated_text;
3080497 }
3080498 //
3080499 // Put environment data inside the stack.
3080500 //
3080501 new_sp -= env_data_size; // --------------
3080502 // ENVIRONMENT
3080503 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080504 (off_t) (stack_location + new_sp),
3080505 env_data, env_data_size, NULL);
3080506 //
3080507 // Put arguments data inside the stack.
3080508 //
3080509 new_sp -= arg_data_size; // ----------------
3080510 // ARGUMENTS
3080511 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080512 (off_t) (stack_location + new_sp),
3080513 arg_data, arg_data_size, NULL);
3080514 //
3080515 // Put envp[] inside the stack, updating all the
3080516 // pointers.
3080517 //
3080518 new_sp -= 4; // --------------------------------- NULL
3080519 stack_element = (uint32_t) NULL;
3080520 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080521 (off_t) (stack_location + new_sp),
3080522 &stack_element, (sizeof stack_element), NULL);
3080523 //
3080524 // Calculate memory pointers from original relative
3080525 // pointers, inside the environment array of
3080526 // pointers.
3080527 //
3080528 p_off = new_sp;
3080529 p_off += 4;
3080530 p_off += arg_data_size;
3080531 for (i = 0; i < envc; i++)
3080532 {
3080533 envp[i] += p_off;
3080534 }
3080535 //
3080536 new_sp -= (envc * (sizeof (char *))); // ----- *envp[]
3080537 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080538 (off_t) (stack_location + new_sp),
3080539 envp, (envc * (sizeof (char *))), NULL);
3080540 //
3080541 // Save the envp[] location, needed in the
3080542 // following.
3080543 //
3080544 envp_address = new_sp;
3080545 //
3080546 // Put argv[] inside the stack, updating all the
3080547 // pointers.
3080548 //
3080549 new_sp -= 4; // -------------------------------- NULL
3080550 stack_element = (uint32_t) NULL;
3080551 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080552 (off_t) (stack_location + new_sp),
3080553 &stack_element, (sizeof stack_element), NULL);
3080554 //
3080555 // Calculate memory pointers from original relative
3080556 // pointers, inside the arguments array of pointers.
3080557 //
3080558 p_off = new_sp;
3080559 p_off += 4;
3080560 p_off += (envc * (sizeof (char *)));
3080561 p_off += 4;
3080562 for (i = 0; i < argc; i++)
3080563 {
3080564 argv[i] += p_off;
3080565 }
3080566 //
3080567 new_sp -= (argc * (sizeof (char *))); // ----- *argv[]
3080568 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080569 (off_t) (stack_location + new_sp),
3080570 argv, (argc * (sizeof (char *))), NULL);
3080571 //
3080572 // Save the argv[] location, needed in the
3080573 // following.
3080574 //
3080575 argv_address = new_sp;
3080576 //
3080577 // Put the pointer to the array envp[].
3080578 //
3080579 new_sp -= 4; // ------------------------------- argc
3080580 stack_element = envp_address;
3080581 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080582 (off_t) (stack_location + new_sp),
3080583 &stack_element, (sizeof stack_element), NULL);
3080584 //
3080585 // Put the pointer to the array argv[].
3080586 //
3080587 new_sp -= 4; // ------------------------------- argc
3080588 stack_element = argv_address;
3080589 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080590 (off_t) (stack_location + new_sp),
3080591 &stack_element, (sizeof stack_element), NULL);
3080592 //
3080593 // Put argc inside the stack.
3080594 //
3080595 new_sp -= 4; // ------------------------------- argc
3080596 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080597 (off_t) (stack_location + new_sp),
3080598 &argc, (sizeof argc), NULL);
3080599 //
3080600 // Set the rest of the stack.
3080601 //
3080602 new_sp -= 4; // ----------------------------- EFLAGS
3080603 stack_element = 0x0200;
3080604 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080605 (off_t) (stack_location + new_sp),
3080606 &stack_element, (sizeof stack_element), NULL);
3080607 new_sp -= 4; // --------------------------------- CS
3080608 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080609 (off_t) (stack_location + new_sp),
3080610 &segment_text, (sizeof segment_text), NULL);
3080611 new_sp -= 4; // -------------------------------- EIP
3080612 stack_element = 0;
3080613 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080614 (off_t) (stack_location + new_sp),
3080615 &stack_element, (sizeof stack_element), NULL);
3080616 new_sp -= 4; // --------------------------------- GS
3080617 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080618 (off_t) (stack_location + new_sp),
3080619 &segment_data, (sizeof segment_data), NULL);
3080620 new_sp -= 4; // --------------------------------- FS
3080621 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080622 (off_t) (stack_location + new_sp),
3080623 &segment_data, (sizeof segment_data), NULL);
3080624 new_sp -= 4; // --------------------------------- ES
3080625 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080626 (off_t) (stack_location + new_sp),
3080627 &segment_data, (sizeof segment_data), NULL);
3080628 new_sp -= 4; // --------------------------------- DS
3080629 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080630 (off_t) (stack_location + new_sp),
3080631 &segment_data, (sizeof segment_data), NULL);
3080632 new_sp -= 4; // -------------------------------- EDI
3080633 stack_element = 0;
3080634 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080635 (off_t) (stack_location + new_sp),
3080636 &stack_element, (sizeof stack_element), NULL);
3080637 new_sp -= 4; // -------------------------------- ESI
3080638 stack_element = 0;
3080639 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080640 (off_t) (stack_location + new_sp),
3080641 &stack_element, (sizeof stack_element), NULL);
3080642 new_sp -= 4; // -------------------------------- EBP
3080643 stack_element = 0;
3080644 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080645 (off_t) (stack_location + new_sp),
3080646 &stack_element, (sizeof stack_element), NULL);
3080647 new_sp -= 4; // -------------------------------- EBX
3080648 stack_element = 0;
3080649 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080650 (off_t) (stack_location + new_sp),
3080651 &stack_element, (sizeof stack_element), NULL);
3080652 new_sp -= 4; // -------------------------------- EDX
3080653 stack_element = 0;
3080654 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080655 (off_t) (stack_location + new_sp),
3080656 &stack_element, (sizeof stack_element), NULL);
3080657 new_sp -= 4; // -------------------------------- ECX
3080658 stack_element = 0;
3080659 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080660 (off_t) (stack_location + new_sp),
3080661 &stack_element, (sizeof stack_element), NULL);
3080662 new_sp -= 4; // -------------------------------- EAX
3080663 stack_element = 0;
3080664 dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE,
3080665 (off_t) (stack_location + new_sp),
3080666 &stack_element, (sizeof stack_element), NULL);
3080667 //
3080668 // Close process file descriptors, if the
3080669 // `FD_CLOEXEC' flag
3080670 // is present.
3080671 //
3080672 for (fdn = 0; fdn < OPEN_MAX; fdn++)
3080673 {
3080674 if (proc_table[pid].fd[0].file != NULL)
3080675 {
3080676 if (proc_table[pid].fd[0].fd_flags & FD_CLOEXEC)
3080677 {
3080678 s_close (pid, fdn);
3080679 }
3080680 }
3080681 }
3080682 //
3080683 // Select device for standard I/O, if a standard I/O
3080684 // stream must be
3080685 // opened.
3080686 //
3080687 if (proc_table[pid].device_tty != 0)
3080688 {
3080689 device = proc_table[pid].device_tty;
3080690 }
3080691 else
3080692 {
3080693 device = DEV_TTY;
3080694 }
3080695 //
3080696 // Prepare missing standard file descriptors. The
3080697 // function
3080698 // `file_stdio_dev_make()' arranges the value for
3080699 // `errno' if
3080700 // necessary. If a standard file descriptor cannot
3080701 // be allocated,
3080702 // the program is left without it.
3080703 //
3080704 if (proc_table[pid].fd[0].file == NULL)
3080705 {
3080706 file =
3080707 file_stdio_dev_make (device, S_IFCHR, O_RDONLY);
3080708 if (file != NULL) // stdin
3080709 {
3080710 proc_table[pid].fd[0].fl_flags = O_RDONLY;
3080711 proc_table[pid].fd[0].fd_flags = 0;
3080712 proc_table[pid].fd[0].file = file;
3080713 proc_table[pid].fd[0].file->offset = 0;
3080714 }
3080715 }
3080716 if (proc_table[pid].fd[1].file == NULL)
3080717 {
3080718 file =
3080719 file_stdio_dev_make (device, S_IFCHR, O_WRONLY);
3080720 if (file != NULL) // stdout
3080721 {
3080722 proc_table[pid].fd[1].fl_flags = O_WRONLY;
3080723 proc_table[pid].fd[1].fd_flags = 0;
3080724 proc_table[pid].fd[1].file = file;
3080725 proc_table[pid].fd[1].file->offset = 0;
3080726 }
3080727 }
3080728 if (proc_table[pid].fd[2].file == NULL)
3080729 {
3080730 file =
3080731 file_stdio_dev_make (device, S_IFCHR, O_WRONLY);
3080732 if (file != NULL) // stderr
3080733 {
3080734 proc_table[pid].fd[2].fl_flags = O_WRONLY;
3080735 proc_table[pid].fd[2].fd_flags = 0;
3080736 proc_table[pid].fd[2].file = file;
3080737 proc_table[pid].fd[2].file->offset = 0;
3080738 }
3080739 }
3080740 //
3080741 // Prepare to switch
3080742 //
3080743 previous_address_text = proc_table[pid].address_text;
3080744 previous_domain_text = proc_table[pid].domain_text;
3080745 previous_address_data = proc_table[pid].address_data;
3080746 previous_domain_data = proc_table[pid].domain_data;
3080747 previous_domain_stack = proc_table[pid].domain_stack;
3080748 previous_extra_data = proc_table[pid].extra_data;
3080749 //
3080750 proc_table[pid].address_text = allocated_text;
3080751 proc_table[pid].domain_text = process_domain_text;
3080752 proc_table[pid].address_data = allocated_data;
3080753 proc_table[pid].domain_data = process_domain_data;
3080754 proc_table[pid].domain_stack = process_domain_stack;
3080755 proc_table[pid].extra_data = (size_t) 0;
3080756 proc_table[pid].sp = new_sp;
3080757 strncpy (proc_table[pid].name, path, PATH_MAX);
3080758 //
3080759 // Ensure to have a terminated string.
3080760 //
3080761 proc_table[pid].name[PATH_MAX - 1] = 0;
3080762 //
3080763 // Reset `sig_handler[]'.
3080764 //
3080765 for (sig = 0; sig < MAX_SIGNALS; sig++)
3080766 {
3080767 proc_table[pid].sig_handler[sig] = (uintptr_t) NULL;
3080768 }
3080769 //
3080770 // Free previous data memory (included stack).
3080771 //
3080772 if (previous_domain_data > 0)
3080773 {
3080774 mb_free (previous_address_data,
3080775 previous_domain_data + previous_extra_data);
3080776 if (DEBUG)
3080777 {
3080778 k_printf ("%s:%i:mb_free(%i, %zi)",
3080779 __FILE__, __LINE__,
3080780 (unsigned int)
3080781 previous_address_data,
3080782 previous_domain_data +
3080783 previous_extra_data);
3080784 }
3080785 }
3080786 //
3080787 // Free code memory if not shared.
3080788 //
3080789 for (proc_count = 0, extra = 0; extra < PROCESS_MAX;
3080790 extra++)
3080791 {
3080792 if (proc_table[extra].status == PROC_EMPTY ||
3080793 proc_table[extra].status == PROC_ZOMBIE)
3080794 {
3080795 continue;
3080796 }
3080797 if (previous_address_text ==
3080798 proc_table[extra].address_text)
3080799 {
3080800 proc_count++;
3080801 }
3080802 }
3080803 if (proc_count == 0)
3080804 {
3080805 //
3080806 // The code segment can be released, because no
3080807 // other
3080808 // process is using it.
3080809 //
3080810 if (previous_domain_data > 0)
3080811 {
3080812 mb_free (previous_address_text,
3080813 previous_domain_text +
3080814 previous_extra_data);
3080815 if (DEBUG)
3080816 {
3080817 k_printf ("%s:%i:mb_free(%i, %zi)",
3080818 __FILE__, __LINE__,
3080819 (unsigned int)
3080820 previous_address_text,
3080821 previous_domain_text +
3080822 previous_extra_data);
3080823 }
3080824 }
3080825 else
3080826 {
3080827 mb_free (previous_address_text,
3080828 previous_domain_text);
3080829 if (DEBUG)
3080830 {
3080831 k_printf ("%s:%i:mb_free(%i, %zi)",
3080832 __FILE__, __LINE__,
3080833 (unsigned int)
3080834 previous_address_text,
3080835 previous_domain_text);
3080836 }
3080837 }
3080838 }
3080839 //
3080840 // Change the segment and the stack pointer, from
3080841 // the interrupt.
3080842 // [1] Anyway,the stack segment selector does not
3080843 // change.
3080844 //
3080845 proc_stack_segment_selector = segment_data; // [1]
3080846 proc_stack_pointer = proc_table[pid].sp;
3080847 //
3080848 //
3080849 //
3080850 return (0);
3080851 }
|
|
94.14.23
kernel/proc/proc_timer_init.c
Si veda la sezione 93.20.22.
3090001 #include <kernel/proc.h>
3090002 #include <stdint.h>
3090003 #include <kernel/lib_k.h>
3090004 #include <kernel/ibm_i386.h>
3090005 #include <stdint.h>
3090006 //----------------------------------------------------------
3090007 void
3090008 proc_timer_init (clock_t freq)
3090009 {
3090010 int input_freq = 1193180;
3090011 //
3090012 // La frequenza di riferimento è 1,19318 MHz, la
3090013 // quale va
3090014 // divisa per la frequenza che si intende avere
3090015 // effettivamente.
3090016 //
3090017 int divisor = input_freq / freq;
3090018 //
3090019 // Il risultato deve essere un valore intero
3090020 // maggiore di zero
3090021 // e inferiore di UINT16_MAX, altrimenti è stata
3090022 // chiesta una
3090023 // frequenza troppo elevata o troppo bassa.
3090024 //
3090025 if (divisor == 0 || divisor > UINT16_MAX)
3090026 {
3090027 k_printf
3090028 ("[%s] ERROR: IRQ 0 frequency wrong: %i Hz!\n"
3090029 "[%s] The min allowed frequency \n"
3090030 "[%s] is 18.22 Hz.\n",
3090031 "[%s] The max allowed frequency \n"
3090032 "[%s] is 1.19 MHz.\n",
3090033 __func__, freq, __func__, __func__, __func__,
3090034 __func__);
3090035 return;
3090036 }
3090037 //
3090038 // Il valore che si ottiene, ovvero il «divisore»,
3090039 // va
3090040 // comunicato al PIT (programmable interval timer),
3090041 // spezzandolo in due parti.
3090042 //
3090043 out_8 ((uint32_t) 0x43, (uint32_t) 0x36);
3090044 //
3090045 // Lower byte.
3090046 //
3090047 out_8 ((uint32_t) 0x40, (uint32_t) (divisor & 0x0F));
3090048 //
3090049 // Higher byte.
3090050 //
3090051 out_8 ((uint32_t) 0x40, (uint32_t) (divisor / 0x10));
3090052 }
|
|
94.14.24
kernel/proc/proc_wakeup_pipe_read.c
Si veda la sezione 93.20.23.
3100001 #include <kernel/proc.h>
3100002 //----------------------------------------------------------
3100003 void
3100004 proc_wakeup_pipe_read (inode_t * inode)
3100005 {
3100006 pid_t pid;
3100007
3100008 for (pid = 1; pid < PROCESS_MAX; pid++)
3100009 {
3100010 if ((proc_table[pid].status == PROC_SLEEPING)
3100011 && (proc_table[pid].wakeup_events
3100012 & WAKEUP_EVENT_PIPE_READ)
3100013 && (proc_table[pid].wakeup_inode == inode))
3100014 {
3100015 proc_table[pid].wakeup_events = 0;
3100016 proc_table[pid].wakeup_inode = NULL;
3100017 proc_table[pid].status = PROC_READY;
3100018 }
3100019 }
3100020 }
|
|
94.14.25
kernel/proc/proc_wakeup_pipe_write.c
Si veda la sezione 93.20.23.
3110001 #include <kernel/proc.h>
3110002 //----------------------------------------------------------
3110003 void
3110004 proc_wakeup_pipe_write (inode_t * inode)
3110005 {
3110006 pid_t pid;
3110007
3110008 for (pid = 1; pid < PROCESS_MAX; pid++)
3110009 {
3110010 if ((proc_table[pid].status == PROC_SLEEPING)
3110011 && (proc_table[pid].wakeup_events
3110012 & WAKEUP_EVENT_PIPE_WRITE)
3110013 && (proc_table[pid].wakeup_inode == inode))
3110014 {
3110015 proc_table[pid].wakeup_events = 0;
3110016 proc_table[pid].wakeup_inode = NULL;
3110017 proc_table[pid].status = PROC_READY;
3110018 }
3110019 }
3110020 }
|
|
94.14.26
kernel/proc/proc_wakeup_terminal.c
Si veda la sezione 93.20.23.
3120001 #include <kernel/proc.h>
3120002 #include <kernel/lib_k.h>
3120003 #include <sys/types.h>
3120004 //----------------------------------------------------------
3120005 void
3120006 proc_wakeup_terminal (void)
3120007 {
3120008 pid_t pid;
3120009 int maj;
3120010 //
3120011 // At the moment, all processes waiting for reading
3120012 // a terminal
3120013 // or the console are reactivated.
3120014 //
3120015 for (pid = 0; pid < PROCESS_MAX; pid++)
3120016 {
3120017 if ((proc_table[pid].status == PROC_SLEEPING)
3120018 && (proc_table[pid].wakeup_events &
3120019 WAKEUP_EVENT_DEV_READ))
3120020 {
3120021 maj = major (proc_table[pid].wakeup_dev);
3120022 if (maj == DEV_TTY_MAJOR
3120023 || maj == DEV_CONSOLE_MAJOR)
3120024 {
3120025 //
3120026 // A process waiting for that terminal
3120027 // was found:
3120028 // remove the waiting event and set it
3120029 // ready.
3120030 //
3120031 proc_table[pid].wakeup_events &=
3120032 ~WAKEUP_EVENT_DEV_READ;
3120033 proc_table[pid].wakeup_dev = 0;
3120034 proc_table[pid].status = PROC_READY;
3120035 }
3120036 }
3120037 }
3120038 }
|
|
94.14.27
kernel/proc/ptr.c
Si veda la sezione 93.20.27.
3130001 #include <kernel/proc.h>
3130002 #include <kernel/lib_s.h>
3130003 #include <kernel/lib_k.h>
3130004 #include <stdint.h>
3130005 //----------------------------------------------------------
3130006 #define DEBUG 0
3130007 //----------------------------------------------------------
3130008 void *
3130009 ptr (pid_t pid, void *p)
3130010 {
3130011 uintptr_t start;
3130012 //
3130013 if (p == NULL)
3130014 {
3130015 return (NULL);
3130016 }
3130017 else if (proc_table[pid].domain_data == 0)
3130018 {
3130019 start = proc_table[pid].address_text;
3130020 }
3130021 else
3130022 {
3130023 start = proc_table[pid].address_data;
3130024 }
3130025 //
3130026 return ((void *) (start + (uintptr_t) p));
3130027 }
|
|
94.14.28
kernel/proc/sysroutine.c
Si veda la sezione 93.20.28.
3140001 #include <kernel/proc.h>
3140002 #include <errno.h>
3140003 #include <kernel/lib_k.h>
3140004 #include <kernel/lib_s.h>
3140005 #include <stdint.h>
3140006 //----------------------------------------------------------
3140007 static void sysroutine_error_back (int *number,
3140008 int *line,
3140009 char *file_name);
3140010 //----------------------------------------------------------
3140011 void
3140012 sysroutine (uint32_t syscallnr, uint32_t msg_off,
3140013 uint32_t msg_size)
3140014 {
3140015 pid_t pid = proc_current;
3140016 //
3140017 // Inbox.
3140018 //
3140019 union
3140020 {
3140021 sysmsg_accept_t accept;
3140022 sysmsg_bind_t bind;
3140023 sysmsg_brk_t brk;
3140024 sysmsg_chdir_t chdir;
3140025 sysmsg_chmod_t chmod;
3140026 sysmsg_chown_t chown;
3140027 sysmsg_clock_t clock;
3140028 sysmsg_close_t close;
3140029 sysmsg_connect_t connect;
3140030 sysmsg_dup_t dup;
3140031 sysmsg_dup2_t dup2;
3140032 sysmsg_exec_t exec;
3140033 sysmsg_exit_t exit;
3140034 sysmsg_fchmod_t fchmod;
3140035 sysmsg_fchown_t fchown;
3140036 sysmsg_fcntl_t fcntl;
3140037 sysmsg_fork_t fork;
3140038 sysmsg_fstat_t fstat;
3140039 sysmsg_ipconfig_t ipconfig;
3140040 sysmsg_jmp_t jmp;
3140041 sysmsg_kill_t kill;
3140042 sysmsg_link_t link;
3140043 sysmsg_listen_t listen;
3140044 sysmsg_lseek_t lseek;
3140045 sysmsg_mkdir_t mkdir;
3140046 sysmsg_mknod_t mknod;
3140047 sysmsg_mount_t mount;
3140048 sysmsg_open_t open;
3140049 sysmsg_pipe_t pipe;
3140050 sysmsg_read_t read;
3140051 sysmsg_recvfrom_t recvfrom;
3140052 sysmsg_route_t route;
3140053 sysmsg_send_t send;
3140054 sysmsg_sbrk_t sbrk;
3140055 sysmsg_seteuid_t seteuid;
3140056 sysmsg_setuid_t setuid;
3140057 sysmsg_setegid_t setegid;
3140058 sysmsg_setgid_t setgid;
3140059 sysmsg_signal_t signal;
3140060 sysmsg_sleep_t sleep;
3140061 sysmsg_socket_t socket;
3140062 sysmsg_stat_t stat;
3140063 sysmsg_stime_t stime;
3140064 sysmsg_tcattr_t tcattr;
3140065 sysmsg_time_t time;
3140066 sysmsg_uarea_t uarea;
3140067 sysmsg_umask_t umask;
3140068 sysmsg_umount_t umount;
3140069 sysmsg_unlink_t unlink;
3140070 sysmsg_wait_t wait;
3140071 sysmsg_write_t write;
3140072 sysmsg_zpchar_t zpchar;
3140073 sysmsg_zpstring_t zpstring;
3140074 } *msg;
3140075 //
3140076 // Align the message address pointer to the source
3140077 // message.
3140078 //
3140079 msg = ptr (pid, (void *) msg_off);
3140080 //
3140081 // Verify if the system call was emitted from kernel
3140082 // code.
3140083 // The kernel can emit only some particular system
3140084 // call:
3140085 // SYS_NULL, to let other processes run;
3140086 // SYS_FORK, to let fork itself;
3140087 // SYS_EXEC, to replace a forked copy of itself.
3140088 //
3140089 if (pid == 0)
3140090 {
3140091 //
3140092 // This is the kernel code!
3140093 //
3140094 if (syscallnr != SYS_0
3140095 && syscallnr != SYS_FORK
3140096 && syscallnr != SYS_EXEC
3140097 && syscallnr != SYS_ZPSTRING)
3140098 {
3140099 k_printf
3140100 ("kernel panic: the system call %i ",
3140101 syscallnr);
3140102 k_printf
3140103 ("was received while running "
3140104 "in kernel space!\n");
3140105 }
3140106 }
3140107 //
3140108 // Entering a system call, the kernel variable
3140109 // `errno' must be
3140110 // reset, otherwise, a previous kernel code error
3140111 // might be returned
3140112 // to the applications.
3140113 //
3140114 errno = 0;
3140115 errln = 0;
3140116 errfn[0] = 0;
3140117 //
3140118 // Do the request from the received system call.
3140119 //
3140120 switch (syscallnr)
3140121 {
3140122 case SYS_0:
3140123 break;
3140124 case SYS_ACCEPT:
3140125 msg->accept.ret =
3140126 s_accept (pid, msg->accept.sfdn,
3140127 &msg->accept.addr, &msg->accept.addrlen);
3140128 msg->accept.fl_flags =
3140129 proc_table[pid].fd[msg->accept.sfdn].fl_flags;
3140130 sysroutine_error_back (&msg->accept.errno,
3140131 &msg->accept.errln,
3140132 msg->accept.errfn);
3140133 break;
3140134 case SYS_BIND:
3140135 msg->bind.ret = s_bind (pid, msg->bind.sfdn,
3140136 &msg->bind.addr,
3140137 msg->bind.addrlen);
3140138 sysroutine_error_back (&msg->bind.errno,
3140139 &msg->bind.errln,
3140140 msg->bind.errfn);
3140141 break;
3140142 case SYS_BRK:
3140143 msg->brk.ret = s_brk (pid, msg->brk.address);
3140144 sysroutine_error_back (&msg->brk.errno,
3140145 &msg->brk.errln,
3140146 msg->brk.errfn);
3140147 break;
3140148 case SYS_CHDIR:
3140149 msg->chdir.ret =
3140150 s_chdir (pid, ptr (pid, (void *) msg->chdir.path));
3140151 sysroutine_error_back (&msg->chdir.errno,
3140152 &msg->chdir.errln,
3140153 msg->chdir.errfn);
3140154 break;
3140155 case SYS_CHMOD:
3140156 msg->chmod.ret = s_chmod (pid,
3140157 ptr (pid,
3140158 (void *) msg->
3140159 chmod.path),
3140160 msg->chmod.mode);
3140161 sysroutine_error_back (&msg->chmod.errno,
3140162 &msg->chmod.errln,
3140163 msg->chmod.errfn);
3140164 break;
3140165 case SYS_CHOWN:
3140166 msg->chown.ret = s_chown (pid,
3140167 ptr (pid,
3140168 (void *) msg->
3140169 chown.path),
3140170 msg->chown.uid,
3140171 msg->chown.gid);
3140172 sysroutine_error_back (&msg->chown.errno,
3140173 &msg->chown.errln,
3140174 msg->chown.errfn);
3140175 break;
3140176 case SYS_CLOCK:
3140177 msg->clock.ret = s_clock (pid);
3140178 break;
3140179 case SYS_CLOSE:
3140180 msg->close.ret = s_close (pid, msg->close.fdn);
3140181 sysroutine_error_back (&msg->close.errno,
3140182 &msg->close.errln,
3140183 msg->close.errfn);
3140184 break;
3140185 case SYS_CONNECT:
3140186 msg->connect.ret =
3140187 s_connect (pid, msg->connect.sfdn,
3140188 &msg->connect.addr,
3140189 msg->connect.addrlen);
3140190 sysroutine_error_back (&msg->connect.errno,
3140191 &msg->connect.errln,
3140192 msg->connect.errfn);
3140193 break;
3140194 case SYS_DUP:
3140195 msg->dup.ret = s_dup (pid, msg->dup.fdn_old);
3140196 sysroutine_error_back (&msg->dup.errno,
3140197 &msg->dup.errln,
3140198 msg->dup.errfn);
3140199 break;
3140200 case SYS_DUP2:
3140201 msg->dup2.ret = s_dup2 (pid, msg->dup2.fdn_old,
3140202 msg->dup2.fdn_new);
3140203 sysroutine_error_back (&msg->dup2.errno,
3140204 &msg->dup2.errln,
3140205 msg->dup2.errfn);
3140206 break;
3140207 case SYS_EXEC:
3140208 msg->exec.ret = proc_sys_exec (pid,
3140209 ptr (pid,
3140210 (void *)
3140211 msg->exec.path),
3140212 msg->exec.argc,
3140213 msg->exec.arg_data,
3140214 msg->exec.envc,
3140215 msg->exec.env_data);
3140216 msg->exec.uid = proc_table[pid].uid;
3140217 msg->exec.euid = proc_table[pid].euid;
3140218 sysroutine_error_back (&msg->exec.errno,
3140219 &msg->exec.errln,
3140220 msg->exec.errfn);
3140221 break;
3140222 case SYS_EXIT:
3140223 if (pid == 0)
3140224 {
3140225 k_printf ("kernel alert: "
3140226 "the kernel cannot exit!\n");
3140227 }
3140228 else
3140229 {
3140230 s__exit (pid, msg->exit.status);
3140231 }
3140232 break;
3140233 case SYS_FCHMOD:
3140234 msg->fchmod.ret = s_fchmod (pid, msg->fchmod.fdn,
3140235 msg->fchmod.mode);
3140236 sysroutine_error_back (&msg->fchmod.errno,
3140237 &msg->fchmod.errln,
3140238 msg->fchmod.errfn);
3140239 break;
3140240 case SYS_FCHOWN:
3140241 msg->fchown.ret = s_fchown (pid, msg->fchown.fdn,
3140242 msg->fchown.uid,
3140243 msg->fchown.gid);
3140244 sysroutine_error_back (&msg->fchown.errno,
3140245 &msg->fchown.errln,
3140246 msg->fchown.errfn);
3140247 break;
3140248 case SYS_FCNTL:
3140249 msg->fcntl.ret = s_fcntl (pid, msg->fcntl.fdn,
3140250 msg->fcntl.cmd,
3140251 msg->fcntl.arg);
3140252 sysroutine_error_back (&msg->fcntl.errno,
3140253 &msg->fcntl.errln,
3140254 msg->fcntl.errfn);
3140255 break;
3140256 case SYS_FORK:
3140257 msg->fork.ret = s_fork (pid);
3140258 sysroutine_error_back (&msg->fork.errno,
3140259 &msg->fork.errln,
3140260 msg->fork.errfn);
3140261 break;
3140262 case SYS_FSTAT:
3140263 msg->fstat.ret =
3140264 s_fstat (pid, msg->fstat.fdn, &msg->fstat.stat);
3140265 sysroutine_error_back (&msg->fstat.errno,
3140266 &msg->fstat.errln,
3140267 msg->fstat.errfn);
3140268 break;
3140269 case SYS_IPCONFIG:
3140270 msg->ipconfig.ret =
3140271 s_ipconfig (pid, msg->ipconfig.n,
3140272 msg->ipconfig.address, msg->ipconfig.m);
3140273 sysroutine_error_back (&msg->ipconfig.errno,
3140274 &msg->ipconfig.errln,
3140275 msg->ipconfig.errfn);
3140276 break;
3140277 case SYS_KILL:
3140278 msg->kill.ret =
3140279 s_kill (pid, msg->kill.pid, msg->kill.signal);
3140280 sysroutine_error_back (&msg->kill.errno,
3140281 &msg->kill.errln,
3140282 msg->kill.errfn);
3140283 break;
3140284 case SYS_LINK:
3140285 msg->link.ret
3140286 = s_link (pid,
3140287 ptr (pid,
3140288 (void *) msg->link.path_old),
3140289 ptr (pid, (void *) msg->link.path_new));
3140290 sysroutine_error_back (&msg->link.errno,
3140291 &msg->link.errln,
3140292 msg->link.errfn);
3140293 break;
3140294 case SYS_LISTEN:
3140295 msg->listen.ret =
3140296 s_listen (pid, msg->listen.sfdn,
3140297 msg->listen.backlog);
3140298 sysroutine_error_back (&msg->listen.errno,
3140299 &msg->listen.errln,
3140300 msg->listen.errfn);
3140301 break;
3140302 case SYS_LONGJMP:
3140303 s_longjmp (pid, msg->jmp.env, msg->jmp.ret);
3140304 break;
3140305 case SYS_LSEEK:
3140306 msg->lseek.ret = s_lseek (pid, msg->lseek.fdn,
3140307 msg->lseek.offset,
3140308 msg->lseek.whence);
3140309 sysroutine_error_back (&msg->lseek.errno,
3140310 &msg->lseek.errln,
3140311 msg->lseek.errfn);
3140312 break;
3140313 case SYS_MKDIR:
3140314 msg->mkdir.ret = s_mkdir (pid,
3140315 ptr (pid,
3140316 (void *) msg->
3140317 mkdir.path),
3140318 msg->mkdir.mode);
3140319 sysroutine_error_back (&msg->mkdir.errno,
3140320 &msg->mkdir.errln,
3140321 msg->mkdir.errfn);
3140322 break;
3140323 case SYS_MKNOD:
3140324 msg->mknod.ret = s_mknod (pid,
3140325 ptr (pid,
3140326 (void *) msg->
3140327 mknod.path),
3140328 msg->mknod.mode,
3140329 msg->mknod.device);
3140330 sysroutine_error_back (&msg->mknod.errno,
3140331 &msg->mknod.errln,
3140332 msg->mknod.errfn);
3140333 break;
3140334 case SYS_MOUNT:
3140335 msg->mount.ret = s_mount (pid,
3140336 ptr (pid,
3140337 (void *) msg->
3140338 mount.path_dev),
3140339 ptr (pid,
3140340 (void *) msg->
3140341 mount.path_mnt),
3140342 msg->mount.options);
3140343 sysroutine_error_back (&msg->mount.errno,
3140344 &msg->mount.errln,
3140345 msg->mount.errfn);
3140346 break;
3140347 case SYS_OPEN:
3140348 msg->open.ret = s_open (pid,
3140349 ptr (pid,
3140350 (void *) msg->open.path),
3140351 msg->open.flags,
3140352 msg->open.mode);
3140353 sysroutine_error_back (&msg->open.errno,
3140354 &msg->open.errln,
3140355 msg->open.errfn);
3140356 break;
3140357 case SYS_PIPE:
3140358 msg->pipe.ret = s_pipe (pid, msg->pipe.pipefd);
3140359 sysroutine_error_back (&msg->pipe.errno,
3140360 &msg->pipe.errln,
3140361 msg->pipe.errfn);
3140362 break;
3140363 case SYS_PGRP:
3140364 proc_table[pid].pgrp = pid;
3140365 break;
3140366 case SYS_READ:
3140367 msg->read.ret = s_read (pid, msg->read.fdn,
3140368 ptr (pid,
3140369 msg->read.buffer),
3140370 msg->read.count);
3140371 msg->read.fl_flags =
3140372 proc_table[pid].fd[msg->read.fdn].fl_flags;
3140373 sysroutine_error_back (&msg->read.errno,
3140374 &msg->read.errln,
3140375 msg->read.errfn);
3140376 break;
3140377 case SYS_RECVFROM:
3140378 msg->recvfrom.ret =
3140379 s_recvfrom
3140380 (pid, msg->recvfrom.sfdn,
3140381 ptr (pid, msg->recvfrom.buffer),
3140382 msg->recvfrom.count,
3140383 msg->recvfrom.flags, ptr (pid,
3140384 msg->recvfrom.addrfrom),
3140385 ptr (pid, msg->recvfrom.addrsize));
3140386 msg->recvfrom.fl_flags =
3140387 proc_table[pid].fd[msg->recvfrom.sfdn].fl_flags;
3140388 sysroutine_error_back (&msg->recvfrom.errno,
3140389 &msg->recvfrom.errln,
3140390 msg->recvfrom.errfn);
3140391 break;
3140392 case SYS_ROUTEADD:
3140393 msg->route.ret =
3140394 s_routeadd (pid, msg->route.destination,
3140395 msg->route.m, msg->route.router,
3140396 msg->route.device);
3140397 sysroutine_error_back (&msg->route.errno,
3140398 &msg->route.errln,
3140399 msg->route.errfn);
3140400 break;
3140401 case SYS_ROUTEDEL:
3140402 msg->route.ret =
3140403 s_routedel (pid, msg->route.destination,
3140404 msg->route.m);
3140405 sysroutine_error_back (&msg->route.errno,
3140406 &msg->route.errln,
3140407 msg->route.errfn);
3140408 break;
3140409 case SYS_SBRK:
3140410 msg->sbrk.ret = s_sbrk (pid, msg->sbrk.increment);
3140411 sysroutine_error_back (&msg->sbrk.errno,
3140412 &msg->sbrk.errln,
3140413 msg->sbrk.errfn);
3140414 break;
3140415 case SYS_SEND:
3140416 msg->send.ret = s_send (pid, msg->send.sfdn,
3140417 ptr (pid,
3140418 (void *) msg->send.
3140419 buffer), msg->send.count,
3140420 msg->send.flags);
3140421 sysroutine_error_back (&msg->send.errno,
3140422 &msg->send.errln,
3140423 msg->send.errfn);
3140424 break;
3140425 case SYS_SETEUID:
3140426 msg->seteuid.ret = s_seteuid (pid, msg->seteuid.euid);
3140427 msg->seteuid.euid = proc_table[pid].euid;
3140428 sysroutine_error_back (&msg->seteuid.errno,
3140429 &msg->seteuid.errln,
3140430 msg->seteuid.errfn);
3140431 break;
3140432 case SYS_SETUID:
3140433 msg->setuid.ret = s_setuid (pid, msg->setuid.euid);
3140434 msg->setuid.uid = proc_table[pid].uid;
3140435 msg->setuid.euid = proc_table[pid].euid;
3140436 msg->setuid.suid = proc_table[pid].suid;
3140437 sysroutine_error_back (&msg->setuid.errno,
3140438 &msg->setuid.errln,
3140439 msg->setuid.errfn);
3140440 break;
3140441 case SYS_SETEGID:
3140442 msg->setegid.ret = s_setegid (pid, msg->setegid.egid);
3140443 msg->setegid.egid = proc_table[pid].egid;
3140444 sysroutine_error_back (&msg->setegid.errno,
3140445 &msg->setegid.errln,
3140446 msg->setegid.errfn);
3140447 break;
3140448 case SYS_SETGID:
3140449 msg->setgid.ret = s_setgid (pid, msg->setgid.egid);
3140450 msg->setgid.gid = proc_table[pid].gid;
3140451 msg->setgid.egid = proc_table[pid].egid;
3140452 msg->setgid.sgid = proc_table[pid].sgid;
3140453 sysroutine_error_back (&msg->setgid.errno,
3140454 &msg->setgid.errln,
3140455 msg->setgid.errfn);
3140456 break;
3140457 case SYS_SETJMP:
3140458 msg->jmp.ret = s_setjmp (pid, msg->jmp.env);
3140459 break;
3140460 case SYS_SIGNAL:
3140461 msg->signal.ret =
3140462 s_signal (pid, msg->signal.signal,
3140463 msg->signal.handler, msg->signal.wrapper);
3140464 sysroutine_error_back (&msg->signal.errno,
3140465 &msg->signal.errln,
3140466 msg->signal.errfn);
3140467 break;
3140468 case SYS_SLEEP:
3140469 proc_table[pid].status = PROC_SLEEPING;
3140470 proc_table[pid].ret = 0;
3140471 proc_table[pid].wakeup_events = msg->sleep.events;
3140472 proc_table[pid].wakeup_timer = msg->sleep.seconds;
3140473 break;
3140474 case SYS_STAT:
3140475 msg->stat.ret = s_stat (pid,
3140476 ptr (pid,
3140477 (void *) msg->stat.path),
3140478 &msg->stat.stat);
3140479 sysroutine_error_back (&msg->stat.errno,
3140480 &msg->stat.errln,
3140481 msg->stat.errfn);
3140482 break;
3140483 case SYS_STIME:
3140484 msg->stime.ret = s_stime (pid, &msg->stime.timer);
3140485 break;
3140486 case SYS_TCGETATTR:
3140487 msg->tcattr.ret =
3140488 s_tcgetattr (pid, msg->tcattr.fdn,
3140489 ptr (pid, msg->tcattr.attr));
3140490 sysroutine_error_back (&msg->tcattr.errno,
3140491 &msg->tcattr.errln,
3140492 msg->tcattr.errfn);
3140493 break;
3140494 case SYS_TCSETATTR:
3140495 msg->tcattr.ret =
3140496 s_tcsetattr (pid, msg->tcattr.fdn,
3140497 msg->tcattr.action, ptr (pid,
3140498 msg->tcattr.
3140499 attr));
3140500 sysroutine_error_back (&msg->tcattr.errno,
3140501 &msg->tcattr.errln,
3140502 msg->tcattr.errfn);
3140503 break;
3140504 case SYS_TIME:
3140505 msg->time.ret = s_time (pid, NULL);
3140506 break;
3140507 case SYS_UAREA:
3140508 msg->uarea.uid = proc_table[pid].uid;
3140509 msg->uarea.suid = proc_table[pid].suid;
3140510 msg->uarea.euid = proc_table[pid].euid;
3140511 msg->uarea.gid = proc_table[pid].gid;
3140512 msg->uarea.sgid = proc_table[pid].sgid;
3140513 msg->uarea.egid = proc_table[pid].egid;
3140514 msg->uarea.pid = pid;
3140515 msg->uarea.ppid = proc_table[pid].ppid;
3140516 msg->uarea.pgrp = proc_table[pid].pgrp;
3140517 msg->uarea.umask = proc_table[pid].umask;
3140518 strncpy (ptr (pid, msg->uarea.path_cwd),
3140519 proc_table[pid].path_cwd,
3140520 msg->uarea.path_cwd_size);
3140521 break;
3140522 case SYS_UMASK:
3140523 msg->umask.ret = proc_table[pid].umask;
3140524 proc_table[pid].umask = (msg->umask.umask & 00777);
3140525 break;
3140526 case SYS_UMOUNT:
3140527 msg->umount.ret = s_umount (pid,
3140528 ptr (pid,
3140529 (void *)
3140530 msg->umount.
3140531 path_mnt));
3140532 sysroutine_error_back (&msg->umount.errno,
3140533 &msg->umount.errln,
3140534 msg->umount.errfn);
3140535 break;
3140536 case SYS_UNLINK:
3140537 msg->unlink.ret = s_unlink (pid,
3140538 ptr (pid,
3140539 (void *) msg->
3140540 unlink.path));
3140541 sysroutine_error_back (&msg->unlink.errno,
3140542 &msg->unlink.errln,
3140543 msg->unlink.errfn);
3140544 break;
3140545 case SYS_WAIT:
3140546 msg->wait.ret = s_wait (pid, &msg->wait.status);
3140547 sysroutine_error_back (&msg->wait.errno,
3140548 &msg->wait.errln,
3140549 msg->wait.errfn);
3140550 break;
3140551 case SYS_WRITE:
3140552 msg->write.ret = s_write (pid, msg->write.fdn,
3140553 ptr (pid,
3140554 (void *) msg->
3140555 write.buffer),
3140556 msg->write.count);
3140557 sysroutine_error_back (&msg->write.errno,
3140558 &msg->write.errln,
3140559 msg->write.errfn);
3140560 break;
3140561 case SYS_SOCKET:
3140562 msg->socket.ret =
3140563 s_socket (pid, msg->socket.family,
3140564 msg->socket.type, msg->socket.protocol);
3140565 sysroutine_error_back (&msg->socket.errno,
3140566 &msg->socket.errln,
3140567 msg->socket.errfn);
3140568 break;
3140569 case SYS_ZPCHAR:
3140570 dev_io (pid, DEV_TTY, DEV_WRITE, 0L,
3140571 &msg->zpchar.c, 1, NULL);
3140572 break;
3140573 case SYS_ZPSTRING:
3140574 dev_io (pid, DEV_TTY, DEV_WRITE, (off_t) 0,
3140575 msg->zpstring.string,
3140576 strlen (msg->zpstring.string), NULL);
3140577 break;
3140578 default:
3140579 k_printf
3140580 ("kernel alert: unknown system call %i!\n",
3140581 syscallnr);
3140582 break;
3140583 }
3140584 //
3140585 // Continue with the scheduler.
3140586 //
3140587 proc_scheduler ();
3140588 }
3140589
3140590 //----------------------------------------------------------
3140591 static void
3140592 sysroutine_error_back (int *number, int *line,
3140593 char *file_name)
3140594 {
3140595 *number = errno;
3140596 *line = errln;
3140597 strncpy (file_name, errfn, PATH_MAX);
3140598 file_name[PATH_MAX - 1] = 0;
3140599 }
|
|
«a2» 2013.11.11 --- Copyright © Daniele Giacomini -- appunti2@gmail.com http://informaticalibera.net