Commit b65b60f4 authored by Linus Torvalds's avatar Linus Torvalds

Linux-0.11 (December 8, 1991)

This was created from a re-packaged 0.11 tree.

Linux-0.11 has a few rather major improvements, but perhaps most
notably, is the first kernel where some other people start making
real contributions.

 - I fixed the buffer cache code, making it a lot more stable

 - demand-loading from disk. My comment proudly states:

        Once more I can proudly say that linux stood up to being changed: it
        was less than 2 hours work to get demand-loading completely implemented.

   This is a major milestone, since it makes the kernel much more
   powerful than Minix was at the time.  I also share clean pages.

 - we still don't have an /sbin/init, but we now load /etc/rc at bootup,
   and the kernel will loop, spawning shells forever. That makes it easier
   to test things.

 - scaffolding for math emulation introduced.

 - Ted Ts'o shows up as a coder. Ted implements:
        o "#!" escape handling for executables
        o fixes for some file permission handling
        o "sticky" directory bit
        o first "malloc()/free()" implementation.
          (this one is horrible: the free needs the size for good
           performance, which will result in years of "free_s()" pains)
        o adds BSD-style setreuid/gid() handling
        o allows us to specify root device at image build time
        o cleanups of some of the uglier direct %fs-register accesses

 - Galen Hunt shows up as a coder: he's added code to handle different
   video card detection (whereas my original one just handled VGA, we
   now handle CGA, MGA, EGA and VGA)

 - The console can beep now: John T Kohl (who also does the tty KILL
   char handling)

 - we also now have German (Wolfgang Thiel) and French (Marc Corsini)
   keyboard maps.  World Domination!

Btw, if you wonder what the "Urgel" comments are - I was still fairly
Swedish-speaking, and "Urgel" is what I would these days write as "Ugh".

It's a sign of trouble or ugly code.  The floppy driver in particular is
clearly not something I'm very proud of ;).
parent fa1ec100
ROOTDEV= /dev/hd3
#
# if you want the ram-disk device, define this to be the
# size in blocks.
#
RAMDISK = #-DRAMDISK=512
AS86 =as -0 -a
CC86 =cc -0
LD86 =ld -0
AS86 =as86 -0 -a
LD86 =ld86 -0
AS =gas
LD =gld
LDFLAGS =-s -x -M
CC =gcc
CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer -fcombine-regs
CC =gcc $(RAMDISK)
CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer \
-fcombine-regs -mstring-insns
CPP =cpp -nostdinc -Iinclude
#
# ROOT_DEV specifies the default root-device when making the image.
# This can be either FLOPPY, /dev/xxxx or empty, in which case the
# default of /dev/hd6 is used by 'build'.
#
ROOT_DEV=/dev/hd6
ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a
MATH =kernel/math/math.a
LIBS =lib/lib.a
.c.s:
......@@ -27,24 +39,30 @@ LIBS =lib/lib.a
all: Image
Image: boot/bootsect boot/setup tools/system tools/build
tools/build boot/bootsect boot/setup tools/system $(ROOTDEV) > Image
tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image
sync
disk: Image
dd bs=8192 if=Image of=/dev/PS0
tools/build: tools/build.c
$(CC) $(CFLAGS) \
-o tools/build tools/build.c
chmem +65000 tools/build
boot/head.o: boot/head.s
tools/system: boot/head.o init/main.o \
$(ARCHIVES) $(DRIVERS) $(LIBS)
$(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS)
$(LD) $(LDFLAGS) boot/head.o init/main.o \
$(ARCHIVES) \
$(DRIVERS) \
$(MATH) \
$(LIBS) \
-o tools/system > System.map
kernel/math/math.a:
(cd kernel/math; make)
kernel/blk_drv/blk_drv.a:
(cd kernel/blk_drv; make)
......@@ -63,30 +81,29 @@ fs/fs.o:
lib/lib.a:
(cd lib; make)
#boot/setup: boot/setup.s
# $(AS86) -o boot/setup.o boot/setup.s
# $(LD86) -s -o boot/setup boot/setup.o
boot/setup: boot/setup.s
$(AS86) -o boot/setup.o boot/setup.s
$(LD86) -s -o boot/setup boot/setup.o
#boot/bootsect: tmp.s
# $(AS86) -o boot/bootsect.o tmp.s
# rm -f tmp.s
# $(LD86) -s -o boot/bootsect boot/bootsect.o
boot/bootsect: boot/bootsect.s
$(AS86) -o boot/bootsect.o boot/bootsect.s
$(LD86) -s -o boot/bootsect boot/bootsect.o
#tmp.s: boot/bootsect.s tools/system
# (echo -n "SYSSIZE = (";ls -l tools/system | grep system \
# | cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
# cat boot/bootsect.s >> tmp.s
tmp.s: boot/bootsect.s tools/system
(echo -n "SYSSIZE = (";ls -l tools/system | grep system \
| cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
cat boot/bootsect.s >> tmp.s
clean:
rm -f Image System.map tmp_make core
rm -f init/*.o boot/*.o tools/system tools/build
rm -f Image System.map tmp_make core boot/bootsect boot/setup
rm -f init/*.o tools/system tools/build boot/*.o
(cd mm;make clean)
(cd fs;make clean)
(cd kernel;make clean)
(cd lib;make clean)
backup: clean
(cd .. ; tar cf - linux | compress16 - > backup.Z)
(cd .. ; tar cf - linux | compress - > backup.Z)
sync
dep:
......
head 1.2;
branch ;
access ;
symbols ;
locks ; strict;
comment @# @;
1.2
date 91.11.11.15.02.48; author tytso; state Exp;
branches ;
next 1.1;
1.1
date 91.11.11.14.43.04; author tytso; state Exp;
branches ;
next ;
desc
@Top level makefile for the Linux kernel
@
1.2
log
@Comment out code to build and clean out 16 bit binaries.
Modify rule to specify the appropriate root device to the build program
@
text
@ROOTDEV= /dev/hd3
AS86 =as -0 -a
CC86 =cc -0
LD86 =ld -0
AS =gas
LD =gld
LDFLAGS =-s -x -M
CC =gcc
CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer -fcombine-regs
CPP =cpp -nostdinc -Iinclude
ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a
LIBS =lib/lib.a
.c.s:
$(CC) $(CFLAGS) \
-nostdinc -Iinclude -S -o $*.s $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) \
-nostdinc -Iinclude -c -o $*.o $<
all: Image
Image: boot/bootsect boot/setup tools/system tools/build
tools/build boot/bootsect boot/setup tools/system $(ROOTDEV) > Image
sync
tools/build: tools/build.c
$(CC) $(CFLAGS) \
-o tools/build tools/build.c
chmem +65000 tools/build
boot/head.o: boot/head.s
tools/system: boot/head.o init/main.o \
$(ARCHIVES) $(DRIVERS) $(LIBS)
$(LD) $(LDFLAGS) boot/head.o init/main.o \
$(ARCHIVES) \
$(DRIVERS) \
$(LIBS) \
-o tools/system > System.map
kernel/blk_drv/blk_drv.a:
(cd kernel/blk_drv; make)
kernel/chr_drv/chr_drv.a:
(cd kernel/chr_drv; make)
kernel/kernel.o:
(cd kernel; make)
mm/mm.o:
(cd mm; make)
fs/fs.o:
(cd fs; make)
lib/lib.a:
(cd lib; make)
#boot/setup: boot/setup.s
# $(AS86) -o boot/setup.o boot/setup.s
# $(LD86) -s -o boot/setup boot/setup.o
#boot/bootsect: tmp.s
# $(AS86) -o boot/bootsect.o tmp.s
# rm -f tmp.s
# $(LD86) -s -o boot/bootsect boot/bootsect.o
#tmp.s: boot/bootsect.s tools/system
# (echo -n "SYSSIZE = (";ls -l tools/system | grep system \
# | cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
# cat boot/bootsect.s >> tmp.s
clean:
rm -f Image System.map tmp_make core
rm -f init/*.o boot/*.o tools/system tools/build
(cd mm;make clean)
(cd fs;make clean)
(cd kernel;make clean)
(cd lib;make clean)
backup: clean
(cd .. ; tar cf - linux | compress16 - > backup.Z)
sync
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
(for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make
cp tmp_make Makefile
(cd fs; make dep)
(cd kernel; make dep)
(cd mm; make dep)
### Dependencies:
init/main.o : init/main.c include/unistd.h include/sys/stat.h \
include/sys/types.h include/sys/times.h include/sys/utsname.h \
include/utime.h include/time.h include/linux/tty.h include/termios.h \
include/linux/sched.h include/linux/head.h include/linux/fs.h \
include/linux/mm.h include/signal.h include/asm/system.h include/asm/io.h \
include/stddef.h include/stdarg.h include/fcntl.h
@
1.1
log
@Initial revision
@
text
@d1 2
d30 1
a30 1
tools/build boot/bootsect boot/setup tools/system > Image
d66 3
a68 3
boot/setup: boot/setup.s
$(AS86) -o boot/setup.o boot/setup.s
$(LD86) -s -o boot/setup boot/setup.o
d70 4
a73 4
boot/bootsect: tmp.s
$(AS86) -o boot/bootsect.o tmp.s
rm -f tmp.s
$(LD86) -s -o boot/bootsect boot/bootsect.o
d75 4
a78 4
tmp.s: boot/bootsect.s tools/system
(echo -n "SYSSIZE = (";ls -l tools/system | grep system \
| cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
cat boot/bootsect.s >> tmp.s
d81 2
a82 2
rm -f Image System.map tmp_make boot/bootsect core
rm -f boot/setup init/*.o boot/*.o tools/system tools/build
@
|
| bootsect.s (C) 1991 Linus Torvalds
|
| bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
| iself out of the way to address 0x90000, and jumps there.
|
| It then loads 'setup' directly after itself (0x90200), and the system
| at 0x10000, using BIOS interrupts.
|
| NOTE! currently system is at most 8*65536 bytes long. This should be no
| problem, even in the future. I want to keep it simple. This 512 kB
| kernel size should be enough, especially as this doesn't contain the
| buffer cache as in minix
|
| The loader has been made as simple as possible, and continuos
| read errors will result in a unbreakable loop. Reboot by hand. It
| loads pretty fast by getting whole sectors at a time whenever possible.
!
! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
! versions of linux
!
SYSSIZE = 0x3000
!
! bootsect.s (C) 1991 Linus Torvalds
!
! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
! iself out of the way to address 0x90000, and jumps there.
!
! It then loads 'setup' directly after itself (0x90200), and the system
! at 0x10000, using BIOS interrupts.
!
! NOTE! currently system is at most 8*65536 bytes long. This should be no
! problem, even in the future. I want to keep it simple. This 512 kB
! kernel size should be enough, especially as this doesn't contain the
! buffer cache as in minix
!
! The loader has been made as simple as possible, and continuos
! read errors will result in a unbreakable loop. Reboot by hand. It
! loads pretty fast by getting whole sectors at a time whenever possible.
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
......@@ -25,16 +31,16 @@ begdata:
begbss:
.text
SETUPLEN = 4 | nr of setup-sectors
BOOTSEG = 0x07c0 | original address of boot-sector
INITSEG = 0x9000 | we move boot here - out of the way
SETUPSEG = 0x9020 | setup starts here
SYSSEG = 0x1000 | system loaded at 0x10000 (65536).
ENDSEG = SYSSEG + SYSSIZE | where to stop loading
SETUPLEN = 4 ! nr of setup-sectors
BOOTSEG = 0x07c0 ! original address of boot-sector
INITSEG = 0x9000 ! we move boot here - out of the way
SETUPSEG = 0x9020 ! setup starts here
SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
| ROOT_DEV: 0x000 - same type of floppy as boot.
| 0x301 - first partition on first drive etc
ROOT_DEV = 0 | 0x306
! ROOT_DEV: 0x000 - same type of floppy as boot.
! 0x301 - first partition on first drive etc
ROOT_DEV = 0x306
entry start
start:
......@@ -51,31 +57,31 @@ start:
go: mov ax,cs
mov ds,ax
mov es,ax
| put stack at 0x9ff00.
! put stack at 0x9ff00.
mov ss,ax
mov sp,#0xFF00 | arbitrary value >>512
mov sp,#0xFF00 ! arbitrary value >>512
| load the setup-sectors directly after the bootblock.
| Note that 'es' is already set up.
! load the setup-sectors directly after the bootblock.
! Note that 'es' is already set up.
load_setup:
mov dx,#0x0000 | drive 0, head 0
mov cx,#0x0002 | sector 2, track 0
mov bx,#0x0200 | address = 512, in INITSEG
mov ax,#0x0200+SETUPLEN | service 2, nr of sectors
int 0x13 | read it
jnc ok_load_setup | ok - continue
mov dx,#0x0000 ! drive 0, head 0
mov cx,#0x0002 ! sector 2, track 0
mov bx,#0x0200 ! address = 512, in INITSEG
mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors
int 0x13 ! read it
jnc ok_load_setup ! ok - continue
mov dx,#0x0000
mov ax,#0x0000 | reset the diskette
mov ax,#0x0000 ! reset the diskette
int 0x13
j load_setup
ok_load_setup:
| Get disk drive parameters, specifically nr of sectors/track
! Get disk drive parameters, specifically nr of sectors/track
mov dl,#0x00
mov ax,#0x0800 | AH=8 is get drive parameters
mov ax,#0x0800 ! AH=8 is get drive parameters
int 0x13
mov ch,#0x00
seg cs
......@@ -83,30 +89,30 @@ ok_load_setup:
mov ax,#INITSEG
mov es,ax
| Print some inane message
! Print some inane message
mov ah,#0x03 | read cursor pos
mov ah,#0x03 ! read cursor pos
xor bh,bh
int 0x10
mov cx,#24
mov bx,#0x0007 | page 0, attribute 7 (normal)
mov bx,#0x0007 ! page 0, attribute 7 (normal)
mov bp,#msg1
mov ax,#0x1301 | write string, move cursor
mov ax,#0x1301 ! write string, move cursor
int 0x10
| ok, we've written the message, now
| we want to load the system (at 0x10000)
! ok, we've written the message, now
! we want to load the system (at 0x10000)
mov ax,#SYSSEG
mov es,ax | segment of 0x010000
mov es,ax ! segment of 0x010000
call read_it
call kill_motor
| After that we check which root-device to use. If the device is
| defined (!= 0), nothing is done and the given device is used.
| Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
| on the number of sectors that the BIOS reports currently.
! After that we check which root-device to use. If the device is
! defined (!= 0), nothing is done and the given device is used.
! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
! on the number of sectors that the BIOS reports currently.
seg cs
mov ax,root_dev
......@@ -114,10 +120,10 @@ ok_load_setup:
jne root_defined
seg cs
mov bx,sectors
mov ax,#0x0208 | /dev/ps0 - 1.2Mb
mov ax,#0x0208 ! /dev/ps0 - 1.2Mb
cmp bx,#15
je root_defined
mov ax,#0x021c | /dev/PS0 - 1.44Mb
mov ax,#0x021c ! /dev/PS0 - 1.44Mb
cmp bx,#18
je root_defined
undef_root:
......@@ -126,30 +132,30 @@ root_defined:
seg cs
mov root_dev,ax
| after that (everyting loaded), we jump to
| the setup-routine loaded directly after
| the bootblock:
! after that (everyting loaded), we jump to
! the setup-routine loaded directly after
! the bootblock:
jmpi 0,SETUPSEG
| This routine loads the system at address 0x10000, making sure
| no 64kB boundaries are crossed. We try to load it as fast as
| possible, loading whole tracks whenever we can.
|
| in: es - starting address segment (normally 0x1000)
|
sread: .word 1+SETUPLEN | sectors read of current track
head: .word 0 | current head
track: .word 0 | current track
! This routine loads the system at address 0x10000, making sure
! no 64kB boundaries are crossed. We try to load it as fast as
! possible, loading whole tracks whenever we can.
!
! in: es - starting address segment (normally 0x1000)
!
sread: .word 1+SETUPLEN ! sectors read of current track
head: .word 0 ! current head
track: .word 0 ! current track
read_it:
mov ax,es
test ax,#0x0fff
die: jne die | es must be at 64kB boundary
xor bx,bx | bx is starting address within segment
die: jne die ! es must be at 64kB boundary
xor bx,bx ! bx is starting address within segment
rp_read:
mov ax,es
cmp ax,#ENDSEG | have we loaded all yet?
cmp ax,#ENDSEG ! have we loaded all yet?
jb ok1_read
ret
ok1_read:
......
/*
*
* bootsect.s (C) 1991 Linus Torvalds
*
* bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
* iself out of the way to address 0x90000, and jumps there.
*
* It then loads 'setup' directly after itself (0x90200), and the system
* at 0x10000, using BIOS interrupts.
*
* NOTE! currently system is at most 8*65536 bytes long. This should be no
* problem, even in the future. I want to keep it simple. This 512 kB
* kernel size should be enough, especially as this doesn't contain the
* buffer cache as in minix
*
* The loader has been made as simple as possible, and continuos
* read errors will result in a unbreakable loop. Reboot by hand. It
* loads pretty fast by getting whole sectors at a time whenever possible.
*/
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text
SETUPLEN = 4 # nr of setup-sectors
BOOTSEG = 0x07c0 # original address of boot-sector
INITSEG = 0x9000 # we move boot here - out of the way
SETUPSEG = 0x9020 # setup starts here
SYSSEG = 0x1000 # system loaded at 0x10000 (65536).
ENDSEG = SYSSEG + SYSSIZE # where to stop loading
/*
* ROOT_DEV: 0x000 - same type of floppy as boot.
* 0x301 - first partition on first drive etc
*/
ROOT_DEV = 0 # 0x306
entry start
start:
mov $BOOTSEG,%ax
mov %ax,%ds
mov $INITSEG,%ax
mov %ax,%es
mov $256,%cx
sub %si,%si
sub %di,%di
rep
movw
jmpi go,INITSEG
go: mov %cs,%ax
mov %ax,%ds
mov %ax,%es
/*
* put stack at 0x9ff00.
*/
mov %ax,%ss
mov $0xFF00,%sp # arbitrary value >>512
/*
* load the setup-sectors directly after the bootblock.
* Note that 'es' is already set up.
*/
load_setup:
mov $0x0000,%dx # drive 0, head 0
mov $0x0002,%cx # sector 2, track 0
mov $0x0200,%bx # address = 512, in INITSEG
mov $0x0200,%ax+SETUPLEN # service 2, nr of sectors
int 0x13 # read it
jnc ok_load_setup # ok - continue
mov $0x0000,%dx
mov $0x0000,%ax # reset the diskette
int 0x13
j load_setup
ok_load_setup:
/*
* Get disk drive parameters, specifically nr of sectors/track
*/
mov $0x00,%dl
mov $0x0800,%ax # AH=8 is get drive parameters
int 0x13
mov $0x00,%ch
seg %cs
mov %cx,sectors
mov $INITSEG,%ax
mov %ax,%es
/*
* Print some inane message
*/
mov $0x03,%ah # read cursor pos
xor %bh,%bh
int 0x10
mov $24,%cx
mov $0x0007,%bx # page 0, attribute 7 (normal)
mov $msg1,%bp
mov $0x1301,%ax # write string, move cursor
int 0x10
/*
* ok, we've written the message, now
* we want to load the system (at 0x10000)
*/
mov $SYSSEG,%ax
mov %ax,%es # segment of 0x010000
call read_it
call kill_motor
/*
* After that we check which root-device to use. If the device is
* defined (!= 0), nothing is done and the given device is used.
* Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
* on the number of sectors that the BIOS reports currently.
*/
seg %cs
mov root,%ax_dev
cmp %ax,$0
jne root_defined
seg %cs
mov sectors,%bx
mov $0x0208,%ax # /dev/ps0 - 1.2Mb
cmp %bx,$15
je root_defined
mov $0x021c,%ax # /dev/PS0 - 1.44Mb
cmp %bx,$18
je root_defined
undef_root:
jmp undef_root
root_defined:
seg %cs
mov root_%ax,dev
/*
* after that (everyting loaded), we jump to
* the setup-routine loaded directly after
* the bootblock:
*/
jmpi 0,SETUPSEG
/*
* This routine loads the system at address 0x10000, making sure
* no 64kB boundaries are crossed. We try to load it as fast as
* possible, loading whole tracks whenever we can.
*
* in: es - starting address segment (normally 0x1000)
*
*/
sread: .word 1+SETUPLEN # sectors read of current track
head: .word 0 # current head
track: .word 0 # current track
read_it:
mov %es,%ax
test %ax,$0x0fff
die: jne die # %es must be at 64kB boundary
xor %bx,%bx # %bx is starting address within segment
rp_read:
mov %es,%ax
cmp %ax,$ENDSEG # have we loaded all yet?
jb ok1_read
ret
ok1_read:
seg %cs
mov sectors,%ax
sub sread,%ax
mov %ax,%cx
shl $9,%cx
add %bx,%cx
jnc ok2_read
je ok2_read
xor %ax,%ax
sub %bx,%ax
shr $9,%ax
ok2_read:
call read_track
mov %ax,%cx
add sread,%ax
seg %cs
cmp %ax,sectors
jne ok3_read
mov $1,%ax
sub head,%ax
jne ok4_read
inc track
ok4_read:
mov %ax,head
xor %ax,%ax
ok3_read:
mov %ax,sread
shl $9,%cx
add %cx,%bx
jnc rp_read
mov %es,%ax
add $0x1000,%ax
mov %ax,%es
xor %bx,%bx
jmp rp_read
read_track:
push %ax
push %bx
push %cx
push %dx
mov track,%dx
mov sread,%cx
inc %cx
mov %dl,%ch
mov head,%dx
mov %dl,%dh
mov $0,%dl
and $0x0100,%dx
mov $2,%ah
int 0x13
jc bad_rt
pop %dx
pop %cx
pop %bx
pop %ax
ret
bad_rt: mov %ax,$0
mov $0,%dx
int 0x13
pop %dx
pop %cx
pop %bx
pop %ax
jmp read_track
/*
* This procedure turns off the floppy drive motor, so
* that we enter the kernel in a known state, and
* don't have to worry about it later.
*/
kill_motor:
push %dx
mov $0x3f2,%dx
mov $0,%al
outb
pop %dx
ret
sectors:
.word 0
msg1:
.byte 13,10
.ascii "Loading system ..."
.byte 13,10,13,10
.org 508
root_dev:
.word ROOT_DEV
boot_flag:
.word 0xAA55
.text
endtext:
.data
enddata:
.bss
endbss:
#!/afs/net/tools/@sys/perl
#
#
$in_block_comment = 0;
while (<>) {
if (/^\|/) {
if (! $in_block_comment) {
print "/* \n";
$in_block_comment = 1;
}
s/\|/ */;
print;
next;
} else {
if ($in_block_comment) {
print " */\n";
$in_block_comment = 0;
}
}
s/#/$/; # Convert immediate references
s/\|/#/; # Convert in-line comments
s/(\b|,)([abcd][xhl])(\b|,|$)/\1%\2\3/g;
s/(\b|,)([cdsefg]s)(\b|,|$)/\1%\2\3/g;
s/(\b|,)([sd]i)(\b|,|$)/\1%\2\3/g;
s/(\b|,)([sb]p)(\b|,|$)/\1%\2\3/g;
s/(\b|,)(e[abcd]x)(\b|,|$)/\1%\2\3/g;
if (/^(([a-zA-Z]+:[ \t]+)|[ \t]+)([a-zA-Z]+)/) {
$op = $3;
if (($op eq "mov") || ($op eq "add") || ($op eq "sub") ||
($op eq "xor") || ($op eq "and") || ($op eq "shr") ||
($op eq "shl") || ($op eq "in") || ($op eq "out")) {
#
# We need to swap arguments...
#
s/([0-9a-zA-Z%\$]+)(,)([0-9a-zA-Z%\$]+)/\3\2\1/;
}
}
print;
}
......@@ -41,15 +41,29 @@ startup_32:
* int 16 for math errors.
*/
movl %cr0,%eax # check math chip
andl $0x80000011,%eax # Save PG,ET,PE
andl $0x80000011,%eax # Save PG,PE,ET
/* "orl $0x10020,%eax" here for 486 might be good */
orl $2,%eax # set MP
testl $0x10,%eax
jne 1f # ET is set - 387 is present
xorl $6,%eax # else reset MP and set EM
1: movl %eax,%cr0
movl %eax,%cr0
call check_x87
jmp after_page_tables
/*
* We depend on ET to be correct. This checks for 287/387.
*/
check_x87:
fninit
fstsw %ax
cmpb $0,%al
je 1f /* no coprocessor: have to set bits */
movl %cr0,%eax
xorl $6,%eax /* reset MP, set EM */
movl %eax,%cr0
ret
.align 2
1: .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */
ret
/*
* setup_idt
*
......
|
| setup.s (C) 1991 Linus Torvalds
|
| setup.s is responsible for getting the system data from the BIOS,
| and putting them into the appropriate places in system memory.
| both setup.s and system has been loaded by the bootblock.
|
| This code asks the bios for memory/disk/other parameters, and
| puts them in a "safe" place: 0x90000-0x901FF, ie where the
| boot-block used to be. It is then up to the protected mode
| system to read them from there before the area is overwritten
| for buffer-blocks.
|
| NOTE! These had better be the same as in bootsect.s!
INITSEG = 0x9000 | we move boot here - out of the way
SYSSEG = 0x1000 | system loaded at 0x10000 (65536).
SETUPSEG = 0x9020 | this is the current segment
!
! setup.s (C) 1991 Linus Torvalds
!
! setup.s is responsible for getting the system data from the BIOS,
! and putting them into the appropriate places in system memory.
! both setup.s and system has been loaded by the bootblock.
!
! This code asks the bios for memory/disk/other parameters, and
! puts them in a "safe" place: 0x90000-0x901FF, ie where the
! boot-block used to be. It is then up to the protected mode
! system to read them from there before the area is overwritten
! for buffer-blocks.
!
! NOTE! These had better be the same as in bootsect.s!
INITSEG = 0x9000 ! we move boot here - out of the way
SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
SETUPSEG = 0x9020 ! this is the current segment
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
......@@ -30,23 +30,39 @@ begbss:
entry start
start:
| ok, the read went well so we get current cursor position and save it for
| posterity.
! ok, the read went well so we get current cursor position and save it for
! posterity.
mov ax,#INITSEG | this is done in bootsect already, but...
mov ax,#INITSEG ! this is done in bootsect already, but...
mov ds,ax
mov ah,#0x03 | read cursor pos
mov ah,#0x03 ! read cursor pos
xor bh,bh
int 0x10 | save it in known place, con_init fetches
mov [0],dx | it from 0x90000.
int 0x10 ! save it in known place, con_init fetches
mov [0],dx ! it from 0x90000.
| Get memory size (extended mem, kB)
! Get memory size (extended mem, kB)
mov ah,#0x88
int 0x15
mov [2],ax
| Get hd0 data
! Get video-card data:
mov ah,#0x0f
int 0x10
mov [4],bx ! bh = display page
mov [6],ax ! al = video mode, ah = window width
! check for EGA/VGA and some config parameters
mov ah,#0x12
mov bl,#0x10
int 0x10
mov [8],ax
mov [10],bx
mov [12],cx
! Get hd0 data
mov ax,#0x0000
mov ds,ax
......@@ -58,7 +74,7 @@ start:
rep
movsb
| Get hd1 data
! Get hd1 data
mov ax,#0x0000
mov ds,ax
......@@ -70,7 +86,7 @@ start:
rep
movsb
| Check that there IS a hd1 :-)
! Check that there IS a hd1 :-)
mov ax,#0x01500
mov dl,#0x81
......@@ -88,20 +104,20 @@ no_disk1:
stosb
is_disk1:
| now we want to move to protected mode ...
! now we want to move to protected mode ...
cli | no interrupts allowed !
cli ! no interrupts allowed !
| first we move the system to it's rightful place
! first we move the system to it's rightful place
mov ax,#0x0000
cld | 'direction'=0, movs moves forward
cld ! 'direction'=0, movs moves forward
do_move:
mov es,ax | destination segment
mov es,ax ! destination segment
add ax,#0x1000
cmp ax,#0x9000
jz end_move
mov ds,ax | source segment
mov ds,ax ! source segment
sub di,di
sub si,si
mov cx,#0x8000
......@@ -109,103 +125,103 @@ do_move:
movsw
jmp do_move
| then we load the segment descriptors
! then we load the segment descriptors
end_move:
mov ax,#SETUPSEG | right, forgot this at first. didn't work :-)
mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-)
mov ds,ax
lidt idt_48 | load idt with 0,0
lgdt gdt_48 | load gdt with whatever appropriate
lidt idt_48 ! load idt with 0,0
lgdt gdt_48 ! load gdt with whatever appropriate
| that was painless, now we enable A20
! that was painless, now we enable A20
call empty_8042
mov al,#0xD1 | command write
mov al,#0xD1 ! command write
out #0x64,al
call empty_8042
mov al,#0xDF | A20 on
mov al,#0xDF ! A20 on
out #0x60,al
call empty_8042
| well, that went ok, I hope. Now we have to reprogram the interrupts :-(
| we put them right after the intel-reserved hardware interrupts, at
| int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
| messed this up with the original PC, and they haven't been able to
| rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
| which is used for the internal hardware interrupts as well. We just
| have to reprogram the 8259's, and it isn't fun.
mov al,#0x11 | initialization sequence
out #0x20,al | send it to 8259A-1
.word 0x00eb,0x00eb | jmp $+2, jmp $+2
out #0xA0,al | and to 8259A-2
! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
! we put them right after the intel-reserved hardware interrupts, at
! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
! messed this up with the original PC, and they haven't been able to
! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
! which is used for the internal hardware interrupts as well. We just
! have to reprogram the 8259's, and it isn't fun.
mov al,#0x11 ! initialization sequence
out #0x20,al ! send it to 8259A-1
.word 0x00eb,0x00eb ! jmp $+2, jmp $+2
out #0xA0,al ! and to 8259A-2
.word 0x00eb,0x00eb
mov al,#0x20 | start of hardware int's (0x20)
mov al,#0x20 ! start of hardware int's (0x20)
out #0x21,al
.word 0x00eb,0x00eb
mov al,#0x28 | start of hardware int's 2 (0x28)
mov al,#0x28 ! start of hardware int's 2 (0x28)
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0x04 | 8259-1 is master
mov al,#0x04 ! 8259-1 is master
out #0x21,al
.word 0x00eb,0x00eb
mov al,#0x02 | 8259-2 is slave
mov al,#0x02 ! 8259-2 is slave
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0x01 | 8086 mode for both
mov al,#0x01 ! 8086 mode for both
out #0x21,al
.word 0x00eb,0x00eb
out #0xA1,al
.word 0x00eb,0x00eb
mov al,#0xFF | mask off all interrupts for now
mov al,#0xFF ! mask off all interrupts for now
out #0x21,al
.word 0x00eb,0x00eb
out #0xA1,al
| well, that certainly wasn't fun :-(. Hopefully it works, and we don't
| need no steenking BIOS anyway (except for the initial loading :-).
| The BIOS-routine wants lots of unnecessary data, and it's less
| "interesting" anyway. This is how REAL programmers do it.
|
| Well, now's the time to actually move into protected mode. To make
| things as simple as possible, we do no register set-up or anything,
| we let the gnu-compiled 32-bit programs do that. We just jump to
| absolute address 0x00000, in 32-bit protected mode.
mov ax,#0x0001 | protected mode (PE) bit
lmsw ax | This is it!
jmpi 0,8 | jmp offset 0 of segment 8 (cs)
| This routine checks that the keyboard command queue is empty
| No timeout is used - if this hangs there is something wrong with
| the machine, and we probably couldn't proceed anyway.
! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
! need no steenking BIOS anyway (except for the initial loading :-).
! The BIOS-routine wants lots of unnecessary data, and it's less
! "interesting" anyway. This is how REAL programmers do it.
!
! Well, now's the time to actually move into protected mode. To make
! things as simple as possible, we do no register set-up or anything,
! we let the gnu-compiled 32-bit programs do that. We just jump to
! absolute address 0x00000, in 32-bit protected mode.
mov ax,#0x0001 ! protected mode (PE) bit
lmsw ax ! This is it!
jmpi 0,8 ! jmp offset 0 of segment 8 (cs)
! This routine checks that the keyboard command queue is empty
! No timeout is used - if this hangs there is something wrong with
! the machine, and we probably couldn't proceed anyway.
empty_8042:
.word 0x00eb,0x00eb
in al,#0x64 | 8042 status port
test al,#2 | is input buffer full?
jnz empty_8042 | yes - loop
in al,#0x64 ! 8042 status port
test al,#2 ! is input buffer full?
jnz empty_8042 ! yes - loop
ret
gdt:
.word 0,0,0,0 | dummy
.word 0,0,0,0 ! dummy
.word 0x07FF | 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 | base address=0
.word 0x9A00 | code read/exec
.word 0x00C0 | granularity=4096, 386
.word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9A00 ! code read/exec
.word 0x00C0 ! granularity=4096, 386
.word 0x07FF | 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 | base address=0
.word 0x9200 | data read/write
.word 0x00C0 | granularity=4096, 386
.word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9200 ! data read/write
.word 0x00C0 ! granularity=4096, 386
idt_48:
.word 0 | idt limit=0
.word 0,0 | idt base=0L
.word 0 ! idt limit=0
.word 0,0 ! idt base=0L
gdt_48:
.word 0x800 | gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 | gdt base = 0X9xxxx
.word 0x800 ! gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 ! gdt base = 0X9xxxx
.text
endtext:
......
/*
*
* setup.s (C) 1991 Linus Torvalds
*
* setup.s is responsible for getting the system data from the BIOS,
* and putting them into the appropriate places in system memory.
* both setup.s and system has been loaded by the bootblock.
*
* This code asks the bios for memory/disk/other parameters, and
* puts them in a "safe" place: 0x90000-0x901FF, ie where the
* boot-block used to be. It is then up to the protected mode
* system to read them from there before the area is overwritten
* for buffer-blocks.
*
*/
/*
* NOTE! These had better be the same as in bootsect.s!
*/
INITSEG = 0x9000 # we move boot here - out of the way
SYSSEG = 0x1000 # system loaded at 0x10000 (65536).
SETUPSEG = 0x9020 # this is the current segment
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text
entry start
start:
/*
* ok, the read went well so we get current cursor position and save it for
* posterity.
*/
mov $INITSEG,%ax # this is done in bootsect already, but...
mov %ax,%ds
mov $0x03,%ah # read cursor pos
xor %bh,%bh
int 0x10 # save it in known place, con_init fetches
mov [0],%dx # it from 0x90000.
/*
* Get memory size (extended mem, kB)
*/
mov $0x88,%ah
int 0x15
mov [2],%ax
/*
* Get hd0 data
*/
mov $0x0000,%ax
mov %ax,%ds
lds %si,[4*0x41]
mov $INITSEG,%ax
mov %ax,%es
mov $0x0080,%di
mov $0x10,%cx
rep
movsb
/*
* Get hd1 data
*/
mov $0x0000,%ax
mov %ax,%ds
lds %si,[4*0x46]
mov $INITSEG,%ax
mov %ax,%es
mov $0x0090,%di
mov $0x10,%cx
rep
movsb
/*
* Check that there IS a hd1 :-)
*/
mov $0x01500,%ax
mov $0x81,%dl
int 0x13
jc no_disk1
cmp %ah,$3
je is_disk1
no_disk1:
mov $INITSEG,%ax
mov %ax,%es
mov $0x0090,%di
mov $0x10,%cx
mov $0x00,%ax
rep
stosb
is_disk1:
/*
* now we want to move to protected mode ...
*/
cli # no interrupts allowed !
/*
* first we move the system to it's rightful place
*/
mov $0x0000,%ax
cld # 'direction'=0, movs moves forward
do_move:
mov %ax,%es # destination segment
add $0x1000,%ax
cmp %ax,$0x9000
jz end_move
mov %ax,%ds # source segment
sub %di,%di
sub %si,%si
mov $0x8000,%cx
rep
movsw
jmp do_move
/*
* then we load the segment descriptors
*/
end_move:
mov $SETUPSEG,%ax # right, forgot this at first. didn't work :-)
mov %ax,%ds
lidt idt_48 # load idt with 0,0
lgdt gdt_48 # load gdt with whatever appropriate
/*
* that was painless, now we enable A20
*/
call empty_8042
mov $0xD1,%al # command write
out %al,$0x64
call empty_8042
mov $0xDF,%al # A20 on
out %al,$0x60
call empty_8042
/*
* well, that went ok, I hope. Now we have to reprogram the interrupts :-(
* we put them right after the intel-reserved hardware interrupts, at
* int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
* messed this up with the original PC, and they haven't been able to
* rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
* which is used for the internal hardware interrupts as well. We just
* have to reprogram the 8259's, and it isn't fun.
*/
mov $0x11,%al # initialization sequence
out %al,$0x20 # send it to 8259A-1
.word 0x00eb,0x00eb # jmp $+2, jmp $+2
out %al,$0xA0 # and to 8259A-2
.word 0x00eb,0x00eb
mov $0x20,%al # start of hardware int's (0x20)
out %al,$0x21
.word 0x00eb,0x00eb
mov $0x28,%al # start of hardware int's 2 (0x28)
out %al,$0xA1
.word 0x00eb,0x00eb
mov $0x04,%al # 8259-1 is master
out %al,$0x21
.word 0x00eb,0x00eb
mov $0x02,%al # 8259-2 is slave
out %al,$0xA1
.word 0x00eb,0x00eb
mov $0x01,%al # 8086 mode for both
out %al,$0x21
.word 0x00eb,0x00eb
out %al,$0xA1
.word 0x00eb,0x00eb
mov $0xFF,%al # mask off all interrupts for now
out %al,$0x21
.word 0x00eb,0x00eb
out %al,$0xA1
/*
* well, that certainly wasn't fun :-(. Hopefully it works, and we don't
* need no steenking BIOS anyway (except for the initial loading :-).
* The BIOS-routine wants lots of unnecessary data, and it's less
* "interesting" anyway. This is how REAL programmers do it.
*
* Well, now's the time to actually move into protected mode. To make
* things as simple as possible, we do no register set-up or anything,
* we let the gnu-compiled 32-bit programs do that. We just jump to
* absolute address 0x00000, in 32-bit protected mode.
*/
mov $0x0001,%ax # protected mode (PE) bit
lmsw %ax # This is it!
jmpi 0,8 # jmp offset 0 of segment 8 (%cs)
/*
* This routine checks that the keyboard command queue is empty
* No timeout is used - if this hangs there is something wrong with
* the machine, and we probably couldn't proceed anyway.
*/
empty_8042:
.word 0x00eb,0x00eb
in $0x64,%al # 8042 status port
test %al,$2 # is input buffer full?
jnz empty_8042 # yes - loop
ret
gdt:
.word 0,0,0,0 # dummy
.word 0x07FF # 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 # base address=0
.word 0x9A00 # code read/exec
.word 0x00C0 # granularity=4096, 386
.word 0x07FF # 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 # base address=0
.word 0x9200 # data read/write
.word 0x00C0 # granularity=4096, 386
idt_48:
.word 0 # idt limit=0
.word 0,0 # idt base=0L
gdt_48:
.word 0x800 # gdt limit=2048, 256 GDT entries
.word 512+gdt,0x9 # gdt base = 0X9xxxx
.text
endtext:
.data
enddata:
.bss
endbss:
......@@ -17,7 +17,7 @@ CPP =gcc -E -nostdinc -I../include
OBJS= open.o read_write.o inode.o file_table.o buffer.o super.o \
block_dev.o char_dev.o file_dev.o stat.o exec.o pipe.o namei.o \
bitmap.o fcntl.o ioctl.o tty_ioctl.o truncate.o
bitmap.o fcntl.o ioctl.o truncate.o
fs.o: $(OBJS)
$(LD) -r -o fs.o $(OBJS)
......@@ -47,10 +47,11 @@ char_dev.o : char_dev.c ../include/errno.h ../include/sys/types.h \
../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \
../include/asm/segment.h ../include/asm/io.h
exec.o : exec.c ../include/errno.h ../include/sys/stat.h \
../include/sys/types.h ../include/a.out.h ../include/linux/fs.h \
../include/linux/sched.h ../include/linux/head.h ../include/linux/mm.h \
../include/signal.h ../include/linux/kernel.h ../include/asm/segment.h
exec.o : exec.c ../include/errno.h ../include/string.h \
../include/sys/stat.h ../include/sys/types.h ../include/a.out.h \
../include/linux/fs.h ../include/linux/sched.h ../include/linux/head.h \
../include/linux/mm.h ../include/signal.h ../include/linux/kernel.h \
../include/asm/segment.h
fcntl.o : fcntl.c ../include/string.h ../include/errno.h \
../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
../include/sys/types.h ../include/linux/mm.h ../include/signal.h \
......@@ -97,8 +98,3 @@ super.o : super.c ../include/linux/config.h ../include/linux/sched.h \
truncate.o : truncate.c ../include/linux/sched.h ../include/linux/head.h \
../include/linux/fs.h ../include/sys/types.h ../include/linux/mm.h \
../include/signal.h ../include/sys/stat.h
tty_ioctl.o : tty_ioctl.c ../include/errno.h ../include/termios.h \
../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \
../include/sys/types.h ../include/linux/mm.h ../include/signal.h \
../include/linux/kernel.h ../include/linux/tty.h ../include/asm/segment.h \
../include/asm/system.h
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
head 1.2;
branch ;
access ;
symbols ;
locks ; strict;
comment @ * @;
1.2
date 91.12.01.09.22.10; author tytso; state Exp;
branches ;
next 1.1;
1.1
date 91.11.21.09.38.53; author tytso; state Exp;
branches ;
next ;
desc
@@
1.2
log
@Patches sent to Linus
@
text
@/*
* linux/fs/open.c
*
* (C) 1991 Linus Torvalds
*/
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <utime.h>
#include <sys/stat.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/kernel.h>
#include <asm/segment.h>
int sys_ustat(int dev, struct ustat * ubuf)
{
return -ENOSYS;
}
int sys_utime(char * filename, struct utimbuf * times)
{
struct m_inode * inode;
long actime,modtime;
if (!(inode=namei(filename)))
return -ENOENT;
if (times) {
actime = get_fs_long((unsigned long *) &times->actime);
modtime = get_fs_long((unsigned long *) &times->modtime);
} else
actime = modtime = CURRENT_TIME;
inode->i_atime = actime;
inode->i_mtime = modtime;
inode->i_dirt = 1;
iput(inode);
return 0;
}
/*
* XXX should we use the real or effective uid? BSD uses the real uid,
* so as to make this call useful to setuid programs.
*/
int sys_access(const char * filename,int mode)
{
struct m_inode * inode;
int res, i_mode;
mode &= 0007;
if (!(inode=namei(filename)))
return -EACCES;
i_mode = res = inode->i_mode & 0777;
iput(inode);
if (current->uid == inode->i_uid)
res >>= 6;
else if (current->gid == inode->i_gid)
res >>= 6;
if ((res & 0007 & mode) == mode)
return 0;
/*
* XXX we are doing this test last because we really should be
* swapping the effective with the real user id (temporarily),
* and then calling suser() routine. If we do call the
* suser() routine, it needs to be called last.
*/
if ((!current->uid) &&
(!(mode & 1) || (i_mode & 0111)))
return 0;
return -EACCES;
}
int sys_chdir(const char * filename)
{
struct m_inode * inode;
if (!(inode = namei(filename)))
return -ENOENT;
if (!S_ISDIR(inode->i_mode)) {
iput(inode);
return -ENOTDIR;
}
iput(current->pwd);
current->pwd = inode;
return (0);
}
int sys_chroot(const char * filename)
{
struct m_inode * inode;
if (!(inode=namei(filename)))
return -ENOENT;
if (!S_ISDIR(inode->i_mode)) {
iput(inode);
return -ENOTDIR;
}
iput(current->root);
current->root = inode;
return (0);
}
int sys_chmod(const char * filename,int mode)
{
struct m_inode * inode;
if (!(inode=namei(filename)))
return -ENOENT;
if ((current->euid != inode->i_uid) && !suser()) {
iput(inode);
return -EACCES;
}
inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
inode->i_dirt = 1;
iput(inode);
return 0;
}
int sys_chown(const char * filename,int uid,int gid)
{
struct m_inode * inode;
if (!(inode=namei(filename)))
return -ENOENT;
if (!suser()) {
iput(inode);
return -EACCES;
}
inode->i_uid=uid;
inode->i_gid=gid;
inode->i_dirt=1;
iput(inode);
return 0;
}
int sys_open(const char * filename,int flag,int mode)
{
struct m_inode * inode;
struct file * f;
int i,fd;
mode &= 0777 & ~current->umask;
for(fd=0 ; fd<NR_OPEN ; fd++)
if (!current->filp[fd])
break;
if (fd>=NR_OPEN)
return -EINVAL;
current->close_on_exec &= ~(1<<fd);
f=0+file_table;
for (i=0 ; i<NR_FILE ; i++,f++)
if (!f->f_count) break;
if (i>=NR_FILE)
return -EINVAL;
(current->filp[fd]=f)->f_count++;
if ((i=open_namei(filename,flag,mode,&inode))<0) {
current->filp[fd]=NULL;
f->f_count=0;
return i;
}
/* ttys are somewhat special (ttyxx major==4, tty major==5) */
if (S_ISCHR(inode->i_mode))
if (MAJOR(inode->i_zone[0])==4) {
if (current->leader && current->tty<0) {
current->tty = MINOR(inode->i_zone[0]);
tty_table[current->tty].pgrp = current->pgrp;
}
} else if (MAJOR(inode->i_zone[0])==5)
if (current->tty<0) {
iput(inode);
current->filp[fd]=NULL;
f->f_count=0;
return -EPERM;
}
/* Likewise with block-devices: check for floppy_change */
if (S_ISBLK(inode->i_mode))
check_disk_change(inode->i_zone[0]);
f->f_mode = inode->i_mode;
f->f_flags = flag;
f->f_count = 1;
f->f_inode = inode;
f->f_pos = 0;
return (fd);
}
int sys_creat(const char * pathname, int mode)
{
return sys_open(pathname, O_CREAT | O_TRUNC, mode);
}
int sys_close(unsigned int fd)
{
struct file * filp;
if (fd >= NR_OPEN)
return -EINVAL;
current->close_on_exec &= ~(1<<fd);
if (!(filp = current->filp[fd]))
return -EINVAL;
current->filp[fd] = NULL;
if (filp->f_count == 0)
panic("Close: file count is 0");
if (--filp->f_count)
return (0);
iput(filp->f_inode);
return (0);
}
@
1.1
log
@Initial revision
@
text
@d43 4
d50 1
a50 1
int res;
d55 1
a55 1
res = inode->i_mode & 0777;
d57 1
a57 6
if (!(current->euid && current->uid))
if (res & 0111)
res = 0777;
else
res = 0666;
if (current->euid == inode->i_uid)
d59 1
a59 1
else if (current->egid == inode->i_gid)
d63 9
d111 4
a114 6
if (current->uid && current->euid)
if (current->uid!=inode->i_uid && current->euid!=inode->i_uid) {
iput(inode);
return -EACCES;
} else
mode = (mode & 0777) | (inode->i_mode & 07000);
d127 1
a127 1
if (current->uid && current->euid) {
@
......@@ -18,12 +18,14 @@ __asm__("cld\n\t" \
#define set_bit(nr,addr) ({\
register int res __asm__("ax"); \
__asm__("btsl %2,%3\n\tsetb %%al":"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
__asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \
"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
res;})
#define clear_bit(nr,addr) ({\
register int res __asm__("ax"); \
__asm__("btrl %2,%3\n\tsetnb %%al":"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
__asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \
"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
res;})
#define find_first_zero(addr) ({ \
......@@ -126,7 +128,7 @@ void free_inode(struct m_inode * inode)
if (!(bh=sb->s_imap[inode->i_num>>13]))
panic("nonexistent imap in superblock");
if (clear_bit(inode->i_num&8191,bh->b_data))
panic("free_inode: bit already cleared");
printk("free_inode: bit already cleared.\n\r");
bh->b_dirt = 1;
memset(inode,0,sizeof(*inode));
}
......@@ -157,6 +159,8 @@ struct m_inode * new_inode(int dev)
inode->i_count=1;
inode->i_nlinks=1;
inode->i_dev=dev;
inode->i_uid=current->euid;
inode->i_gid=current->egid;
inode->i_dirt=1;
inode->i_num = j + i*8192;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
......
......@@ -81,6 +81,21 @@ int sync_dev(int dev)
return 0;
}
void inline invalidate_buffers(int dev)
{
int i;
struct buffer_head * bh;
bh = start_buffer;
for (i=0 ; i<NR_BUFFERS ; i++,bh++) {
if (bh->b_dev != dev)
continue;
wait_on_buffer(bh);
if (bh->b_dev == dev)
bh->b_uptodate = bh->b_dirt = 0;
}
}
/*
* This routine checks whether a floppy has been changed, and
* invalidates all buffer-cache-entries in that case. This
......@@ -98,25 +113,16 @@ int sync_dev(int dev)
void check_disk_change(int dev)
{
int i;
struct buffer_head * bh;
if (MAJOR(dev) != 2)
return;
dev=MINOR(dev) & 0x03; /* which floppy is it? */
if (!floppy_change(dev))
if (!floppy_change(dev & 0x03))
return;
dev |= 0x200;
for (i=0 ; i<NR_SUPER ; i++)
if ((super_block[i].s_dev & 0xff03)==dev)
if (super_block[i].s_dev == dev)
put_super(super_block[i].s_dev);
bh = start_buffer;
for (i=0 ; i<NR_BUFFERS ; i++,bh++) {
if ((bh->b_dev & 0xff03) != dev)
continue;
wait_on_buffer(bh);
if ((bh->b_dev & 0xff03) == dev)
bh->b_uptodate = bh->b_dirt = 0;
}
invalidate_inodes(dev);
invalidate_buffers(dev);
}
#define _hashfn(dev,block) (((unsigned)(dev^block))%NR_HASH)
......@@ -194,8 +200,7 @@ struct buffer_head * get_hash_table(int dev, int block)
* race-conditions. Most of the code is seldom used, (ie repeating),
* so it should be much more efficient than it looks.
*
* The algoritm is changed: better, and an elusive bug removed.
* LBT 11.11.91
* The algoritm is changed: hopefully better, and an elusive bug removed.
*/
#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
struct buffer_head * getblk(int dev,int block)
......@@ -214,6 +219,7 @@ struct buffer_head * getblk(int dev,int block)
if (!BADNESS(tmp))
break;
}
/* and repeat until we find something good */
} while ((tmp = tmp->b_next_free) != free_list);
if (!bh) {
sleep_on(&buffer_wait);
......@@ -274,6 +280,40 @@ struct buffer_head * bread(int dev,int block)
return NULL;
}
#define COPYBLK(from,to) \
__asm__("cld\n\t" \
"rep\n\t" \
"movsl\n\t" \
::"c" (BLOCK_SIZE/4),"S" (from),"D" (to) \
:"cx","di","si")
/*
* bread_page reads four buffers into memory at the desired address. It's
* a function of its own, as there is some speed to be got by reading them
* all at the same time, not waiting for one to be read, and then another
* etc.
*/
void bread_page(unsigned long address,int dev,int b[4])
{
struct buffer_head * bh[4];
int i;
for (i=0 ; i<4 ; i++)
if (b[i]) {
if (bh[i] = getblk(dev,b[i]))
if (!bh[i]->b_uptodate)
ll_rw_block(READ,bh[i]);
} else
bh[i] = NULL;
for (i=0 ; i<4 ; i++,address += BLOCK_SIZE)
if (bh[i]) {
wait_on_buffer(bh[i]);
if (bh[i]->b_uptodate)
COPYBLK((unsigned long) bh[i]->b_data,address);
brelse(bh[i]);
}
}
/*
* Ok, breada can be used as bread, but additionally to mark other
* blocks for reading as well. End the argument list with a negative
......
......@@ -97,10 +97,8 @@ int rw_char(int rw,int dev, char * buf, int count, off_t * pos)
crw_ptr call_addr;
if (MAJOR(dev)>=NRDEVS)
panic("rw_char: dev>NRDEV");
if (!(call_addr=crw_table[MAJOR(dev)])) {
printk("dev: %04x\n",dev);
panic("Trying to r/w from/to nonexistent character device");
}
return -ENODEV;
if (!(call_addr=crw_table[MAJOR(dev)]))
return -ENODEV;
return call_addr(rw,MINOR(dev),buf,count,pos);
}
......@@ -4,6 +4,19 @@
* (C) 1991 Linus Torvalds
*/
/*
* #!-checking implemented by tytso.
*/
/*
* Demand-loading implemented 01.12.91 - no need to read anything but
* the header into memory. The inode of the executable is put into
* "current->executable", and page faults do the actual loading. Clean.
*
* Once more I can proudly say that linux stood up to being changed: it
* was less than 2 hours work to get demand-loading completely implemented.
*/
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
......@@ -25,96 +38,6 @@ extern int sys_close(int fd);
*/
#define MAX_ARG_PAGES 32
#define cp_block(from,to) \
__asm__("pushl $0x10\n\t" \
"pushl $0x17\n\t" \
"pop %%es\n\t" \
"cld\n\t" \
"rep\n\t" \
"movsl\n\t" \
"pop %%es" \
::"c" (BLOCK_SIZE/4),"S" (from),"D" (to) \
:"cx","di","si")
/*
* read_head() reads blocks 1-6 (not 0). Block 0 has already been
* read for header information.
*/
int read_head(struct m_inode * inode,int blocks)
{
struct buffer_head * bh;
int count;
if (blocks>6)
blocks=6;
for(count = 0 ; count<blocks ; count++) {
if (!inode->i_zone[count+1])
continue;
if (!(bh=bread(inode->i_dev,inode->i_zone[count+1])))
return -1;
cp_block(bh->b_data,count*BLOCK_SIZE);
brelse(bh);
}
return 0;
}
int read_ind(int dev,int ind,long size,unsigned long offset)
{
struct buffer_head * ih, * bh;
unsigned short * table,block;
if (size<=0)
panic("size<=0 in read_ind");
if (size>512*BLOCK_SIZE)
size=512*BLOCK_SIZE;
if (!ind)
return 0;
if (!(ih=bread(dev,ind)))
return -1;
table = (unsigned short *) ih->b_data;
while (size>0) {
if (block=*(table++))
if (!(bh=bread(dev,block))) {
brelse(ih);
return -1;
} else {
cp_block(bh->b_data,offset);
brelse(bh);
}
size -= BLOCK_SIZE;
offset += BLOCK_SIZE;
}
brelse(ih);
return 0;
}
/*
* read_area() reads an area into %fs:mem.
*/
int read_area(struct m_inode * inode,long size)
{
struct buffer_head * dind;
unsigned short * table;
int i,count;
if ((i=read_head(inode,(size+BLOCK_SIZE-1)/BLOCK_SIZE)) ||
(size -= BLOCK_SIZE*6)<=0)
return i;
if ((i=read_ind(inode->i_dev,inode->i_zone[7],size,BLOCK_SIZE*6)) ||
(size -= BLOCK_SIZE*512)<=0)
return i;
if (!(i=inode->i_zone[8]))
return 0;
if (!(dind = bread(inode->i_dev,i)))
return -1;
table = (unsigned short *) dind->b_data;
for(count=0 ; count<512 ; count++)
if ((i=read_ind(inode->i_dev,*(table++),size,
BLOCK_SIZE*(518+count))) || (size -= BLOCK_SIZE*512)<=0)
return i;
panic("Impossibly long executable");
}
/*
* create_tables() parses the env- and arg-strings in new user
* memory and creates the pointer tables from them, and puts their
......@@ -267,7 +190,6 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
int e_uid, e_gid;
int retval;
int sh_bang = 0;
char *buf = 0;
unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4;
if ((0xffff & eip[1]) != 0x000f)
......@@ -307,11 +229,9 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
* Sorta complicated, but hopefully it will work. -TYT
*/
char *cp, *interp, *i_name, *i_arg;
char buf[1023], *cp, *interp, *i_name, *i_arg;
unsigned long old_fs;
if (!buf)
buf = malloc(1024);
strncpy(buf, bh->b_data+2, 1022);
brelse(bh);
iput(inode);
......@@ -396,8 +316,9 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
}
}
/* OK, This is the point of no return */
if (buf)
free_s(buf, 1024);
if (current->executable)
iput(current->executable);
current->executable = inode;
for (i=0 ; i<32 ; i++)
current->sigaction[i].sa_handler = NULL;
for (i=0 ; i<NR_OPEN ; i++)
......@@ -417,10 +338,6 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
current->start_stack = p & 0xfffff000;
current->euid = e_uid;
current->egid = e_gid;
i = read_area(inode,ex.a_text+ex.a_data);
iput(inode);
if (i<0)
sys_exit(-1);
i = ex.a_text+ex.a_data;
while (i&0xfff)
put_fs_byte(0,(char *) (i++));
......@@ -430,8 +347,6 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
exec_error2:
iput(inode);
exec_error1:
if (buf)
free(buf);
for (i=0 ; i<MAX_ARG_PAGES ; i++)
free_page(page[i]);
return(retval);
......
This diff is collapsed.
This diff is collapsed.
......@@ -40,6 +40,22 @@ static inline void unlock_inode(struct m_inode * inode)
wake_up(&inode->i_wait);
}
void invalidate_inodes(int dev)
{
int i;
struct m_inode * inode;
inode = 0+inode_table;
for(i=0 ; i<NR_INODE ; i++,inode++) {
wait_on_inode(inode);
if (inode->i_dev == dev) {
if (inode->i_count)
printk("inode in use on removed disk\n\r");
inode->i_dev = inode->i_dirt = 0;
}
}
}
void sync_inodes(void)
{
int i;
......@@ -148,15 +164,19 @@ void iput(struct m_inode * inode)
inode->i_pipe=0;
return;
}
if (!inode->i_dev || inode->i_count>1) {
if (!inode->i_dev) {
inode->i_count--;
return;
}
repeat:
if (S_ISBLK(inode->i_mode)) {
sync_dev(inode->i_zone[0]);
wait_on_inode(inode);
}
repeat:
if (inode->i_count>1) {
inode->i_count--;
return;
}
if (!inode->i_nlinks) {
truncate(inode);
free_inode(inode);
......@@ -171,40 +191,35 @@ void iput(struct m_inode * inode)
return;
}
static volatile int last_allocated_inode = 0;
struct m_inode * get_empty_inode(void)
{
struct m_inode * inode;
int inr;
static struct m_inode * last_inode = inode_table;
int i;
while (1) {
do {
inode = NULL;
inr = last_allocated_inode;
do {
if (!inode_table[inr].i_count) {
inode = inr + inode_table;
break;
for (i = NR_INODE; i ; i--) {
if (++last_inode >= inode_table + NR_INODE)
last_inode = inode_table;
if (!last_inode->i_count) {
inode = last_inode;
if (!inode->i_dirt && !inode->i_lock)
break;
}
inr++;
if (inr>=NR_INODE)
inr=0;
} while (inr != last_allocated_inode);
}
if (!inode) {
for (inr=0 ; inr<NR_INODE ; inr++)
printk("%04x: %6d\t",inode_table[inr].i_dev,
inode_table[inr].i_num);
for (i=0 ; i<NR_INODE ; i++)
printk("%04x: %6d\t",inode_table[i].i_dev,
inode_table[i].i_num);
panic("No free inodes in mem");
}
last_allocated_inode = inr;
wait_on_inode(inode);
while (inode->i_dirt) {
write_inode(inode);
wait_on_inode(inode);
}
if (!inode->i_count)
break;
}
} while (inode->i_count);
memset(inode,0,sizeof(*inode));
inode->i_count = 1;
return inode;
......@@ -283,7 +298,8 @@ static void read_inode(struct m_inode * inode)
int block;
lock_inode(inode);
sb=get_super(inode->i_dev);
if (!(sb=get_super(inode->i_dev)))
panic("trying to read inode without dev");
block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
(inode->i_num-1)/INODES_PER_BLOCK;
if (!(bh=bread(inode->i_dev,block)))
......@@ -302,7 +318,12 @@ static void write_inode(struct m_inode * inode)
int block;
lock_inode(inode);
sb=get_super(inode->i_dev);
if (!inode->i_dirt || !inode->i_dev) {
unlock_inode(inode);
return;
}
if (!(sb=get_super(inode->i_dev)))
panic("trying to write inode without device");
block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
(inode->i_num-1)/INODES_PER_BLOCK;
if (!(bh=bread(inode->i_dev,block)))
......
......@@ -39,7 +39,7 @@ int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return -EINVAL;
dev = filp->f_inode->i_zone[0];
if (MAJOR(dev) >= NRDEVS)
panic("unknown device for ioctl");
return -ENODEV;
if (!ioctl_table[MAJOR(dev)])
return -ENOTTY;
return ioctl_table[MAJOR(dev)](dev,cmd,arg);
......
......@@ -4,6 +4,10 @@
* (C) 1991 Linus Torvalds
*/
/*
* Some corrections by tytso.
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
......@@ -76,7 +80,7 @@ static int match(int len,const char * name,struct dir_entry * de)
/*
* find_entry()
*
* finds and entry in the specified directory with the wanted name. It
* finds an entry in the specified directory with the wanted name. It
* returns the cache buffer in which the entry was found, and the entry
* itself (as a parameter - res_dir). It does NOT read the inode of the
* entry - you'll have to do that yourself if you want to.
......@@ -596,18 +600,30 @@ int sys_rmdir(const char * name)
iput(dir);
return -ENOENT;
}
if (!permission(dir,MAY_WRITE)) {
iput(dir);
return -EPERM;
}
bh = find_entry(&dir,basename,namelen,&de);
if (!bh) {
iput(dir);
return -ENOENT;
}
if (!permission(dir,MAY_WRITE)) {
if (!(inode = iget(dir->i_dev, de->inode))) {
iput(dir);
brelse(bh);
return -EPERM;
}
if (!(inode = iget(dir->i_dev, de->inode))) {
if ((dir->i_mode & S_ISVTX) && current->euid &&
inode->i_uid != current->euid) {
iput(dir);
iput(inode);
brelse(bh);
return -EPERM;
}
if (inode->i_dev != dir->i_dev || inode->i_count>1) {
iput(dir);
iput(inode);
brelse(bh);
return -EPERM;
}
......@@ -667,32 +683,25 @@ int sys_unlink(const char * name)
iput(dir);
return -ENOENT;
}
inode = iget(dir->i_dev, de->inode);
if (!inode) {
printk("iget failed in delete (%04x:%d)",dir->i_dev,de->inode);
if (!(inode = iget(dir->i_dev, de->inode))) {
iput(dir);
brelse(bh);
return -ENOENT;
}
if (S_ISDIR(inode->i_mode)) {
iput(inode);
if ((dir->i_mode & S_ISVTX) && !suser() &&
current->euid != inode->i_uid &&
current->euid != dir->i_uid) {
iput(dir);
iput(inode);
brelse(bh);
return -EPERM;
}
/*
* If the directory has the sticky bit, the user must either
* own the file or own the directory or be the superuser to
* delete a file in that directory. This is typically used
* for /tmp and /usr/tmp.
*/
if ((dir->i_mode & S_ISVTX) && (current->euid != inode->i_uid) &&
(current->euid != dir->i_uid) && !suser()) {
if (S_ISDIR(inode->i_mode)) {
iput(inode);
iput(dir);
brelse(bh);
return -EPERM;
}
}
if (!inode->i_nlinks) {
printk("Deleting nonexistent file (%04x:%d), %d\n",
inode->i_dev,inode->i_num,inode->i_nlinks);
......
This diff is collapsed.
This diff is collapsed.
......@@ -64,7 +64,7 @@ int sys_read(unsigned int fd,char * buf,int count)
verify_area(buf,count);
inode = file->f_inode;
if (inode->i_pipe)
return (file->f_mode&1)?read_pipe(inode,buf,count):-1;
return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO;
if (S_ISCHR(inode->i_mode))
return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos);
if (S_ISBLK(inode->i_mode))
......@@ -91,7 +91,7 @@ int sys_write(unsigned int fd,char * buf,int count)
return 0;
inode=file->f_inode;
if (inode->i_pipe)
return (file->f_mode&2)?write_pipe(inode,buf,count):-1;
return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO;
if (S_ISCHR(inode->i_mode))
return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos);
if (S_ISBLK(inode->i_mode))
......
......@@ -74,6 +74,7 @@ struct super_block * get_super(int dev)
void put_super(int dev)
{
struct super_block * sb;
struct m_inode * inode;
int i;
if (dev == ROOT_DEV) {
......@@ -183,9 +184,9 @@ int sys_umount(char * dev_name)
return -ENOENT;
if (!sb->s_imount->i_mount)
printk("Mounted inode has i_mount=0\n");
for(inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)
for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)
if (inode->i_dev==dev && inode->i_count)
return -EBUSY;
return -EBUSY;
sb->s_imount->i_mount=0;
iput(sb->s_imount);
sb->s_imount = NULL;
......
head 1.2;
branch ;
access ;
symbols ;
locks ; strict;
comment @ * @;
1.2
date 91.11.15.19.30.40; author tytso; state Exp;
branches ;
next 1.1;
1.1
date 91.11.15.16.16.12; author tytso; state Exp;
branches ;
next ;
desc
@@
1.2
log
@Fixed bug in tolower(). Plus sign should have been a minus sign.
@
text
@#ifndef _CTYPE_H
#define _CTYPE_H
#define _U 0x01 /* upper */
#define _L 0x02 /* lower */
#define _D 0x04 /* digit */
#define _C 0x08 /* cntrl */
#define _P 0x10 /* punct */
#define _S 0x20 /* white space (space/lf/tab) */
#define _X 0x40 /* hex digit */
#define _SP 0x80 /* hard space (0x20) */
extern unsigned char _ctype[];
extern char _ctmp;
#define isalnum(c) ((_ctype+1)[c]&(_U|_L|_D))
#define isalpha(c) ((_ctype+1)[c]&(_U|_L))
#define iscntrl(c) ((_ctype+1)[c]&(_C))
#define isdigit(c) ((_ctype+1)[c]&(_D))
#define isgraph(c) ((_ctype+1)[c]&(_P|_U|_L|_D))
#define islower(c) ((_ctype+1)[c]&(_L))
#define isprint(c) ((_ctype+1)[c]&(_P|_U|_L|_D|_SP))
#define ispunct(c) ((_ctype+1)[c]&(_P))
#define isspace(c) ((_ctype+1)[c]&(_S))
#define isupper(c) ((_ctype+1)[c]&(_U))
#define isxdigit(c) ((_ctype+1)[c]&(_D|_X))
#define isascii(c) (((unsigned) c)<=0x7f)
#define toascii(c) (((unsigned) c)&0x7f)
#define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp+('a'-'A'):_ctmp)
#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp+('A'-'a'):_ctmp)
#endif
@
1.1
log
@Initial revision
@
text
@d31 1
a31 1
#define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp+('a'+'A'):_ctmp)
@
This diff is collapsed.
......@@ -41,6 +41,7 @@ __asm__ ("movl %0,%%fs:%1"::"r" (val),"m" (*addr));
* Someone who knows GNU asm better than I should double check the followig.
* It seems to work, but I don't know if I'm doing something subtly wrong.
* --- TYT, 11/24/91
* [ nothing wrong here, Linus ]
*/
extern inline unsigned long get_fs()
......@@ -62,4 +63,3 @@ extern inline void set_fs(unsigned long val)
__asm__("mov %0,%%fs"::"a" ((unsigned short) val));
}
......@@ -28,7 +28,7 @@ extern char _ctmp;
#define isascii(c) (((unsigned) c)<=0x7f)
#define toascii(c) (((unsigned) c)&0x7f)
#define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp+('a'-'A'):_ctmp)
#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp+('A'-'a'):_ctmp)
#define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp-('A'-'a'):_ctmp)
#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp)
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -33,4 +33,5 @@ dep:
### Dependencies:
memory.o : memory.c ../include/signal.h ../include/sys/types.h \
../include/linux/head.h ../include/linux/kernel.h ../include/asm/system.h
../include/asm/system.h ../include/linux/sched.h ../include/linux/head.h \
../include/linux/fs.h ../include/linux/mm.h ../include/linux/kernel.h
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment