add directory distributions

This commit is contained in:
gohigh
2024-02-19 00:23:20 -05:00
parent eb168dd24f
commit b50063d9b3
934 changed files with 101264 additions and 0 deletions

BIN
distributions/cnix/FAT.pdf Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,82 @@
#
# Makefile for cnix.
AS = as
LD = ld
LDFLAGS = -m elf_i386 -Ttext 0x100000 -e on_journey
CC = gcc $(RAMDISK)
CFLAGS = -Wall -O2 -fstrength-reduce -fomit-frame-pointer \
-finline-functions -nostdinc -I../include
CPP = cpp -nostdinc -Iinclude
ARCHIVES = driver/driver.o mm/mm.o fs/fs.o kernel/kernel.o shell/shell.o
LIBS = lib/lib.a
all: Image
Image: boot/boot tools/system tools/build
objcopy -O binary -R .note -R .comment tools/system tools/kernel
tools/build boot/boot tools/kernel > Image
tools/ndisasm -b32 tools/kernel > System.asm
rm tools/kernel -f
sync
disk: Image tools/makeimg
tools/makeimg Image a.img
tools/build:
(cd tools; make)
tools/system: boot/head.o init/main.o \
$(ARCHIVES) $(LIBS)
$(LD) $(LDFLAGS) boot/head.o init/main.o \
$(ARCHIVES) \
$(LIBS) \
-o tools/system
nm tools/system | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)'| sort > System.map
init/main.o:
(cd init;make)
boot/boot: boot/boot.o tools/system
$(LD) -Ttext 0x0 -s --oformat binary -o $@ boot/boot.o
boot/boot.o: boot/boot.s
$(AS) -o $@ $<
boot/boot.s: boot/boot.S
$(CC) $(CFLAGS) -S $<>$@
boot/head.o: boot/head.s
$(AS) -o $@ $<
boot/head.s: boot/head.S
$(CC) $(CFLAGS) -S $<>$@
driver/driver.o:
(cd driver;make)
shell/shell.o:
(cd shell;make)
# need to be modified
mm/mm.o:
(cd mm;make)
fs/fs.o:
(cd fs;make)
kernel/kernel.o:
(cd kernel;make)
lib/lib.a:
(cd lib;make)
clean:
rm -f Image a.img System.map tmp_make boot/boot core
rm -f boot/*.o tools/system System.asm
rm -f *~ boot/*~ tools/*~ include/*~ include/asm/*~ include/cnix/*~
rm -f .*.swp boot/.*.swp include/.*.swp include/asm/.*.swp include/cnix/.*.swp
(cd tools; make clean)
(cd driver;make clean)
(cd kernel;make clean)
(cd init;make clean)
(cd shell;make clean)
(cd mm;make clean)
(cd fs;make clean)
(cd lib;make clean)

View File

@@ -0,0 +1,256 @@
/*
* boot.S
* After being loaded at address 0x7c00, it loads the kernel to address 0x10000.
* Then disables all the interrupts and enter the protected mode. And jumps to
* the kernel.
*/
BOOTSEG = 0x07c0
SYSSEG = 0x1000
SYSSIZE = 0x3000 # Max value may be 0x9000.
SYSEND = SYSSEG + SYSSIZE
# For 1.44M.
sectors = 18
.code16
.text
.global _start
_start:
movw $BOOTSEG, %ax
movw %ax, %ds
movw %ax, %es
cli
movw %ax, %ss
movw $0x8000, %sp # 0x8000 + 0x7c00 < 0x10000
sti
movb $3, %ah
xorb %bh, %bh
int $0x10
movw $0x1301, %ax
movw $0x0007, %bx
movw $message, %bp
movw $9, %cx
int $0x10
movw $SYSSEG, %ax
movw %ax, %es
call read_kernel
call kill_motor
# Save the current cursor at address 0x7c00 + 510, 0x7c00 + 511.
movb $3, %ah
xorb %bh, %bh
int $0x10
movw %dx, (510)
# Now it's time to enter protected mode.
cli
lidt idt_pdesc
lgdt gdt_pdesc
# Enable a20.
call kb_wait
movb $0xd1, %al # command write.
outb %al, $0x64
call kb_wait
movb $0xdf, %al # enable a20.
outb %al, $0x60
call kb_wait
# Assume all things is ok. Go on to initialize 8259.
movb $0x11, %al # initialize sequence.
outb %al, $0x20
call delay
outb %al, $0xa0
call delay
movb $0x20, %al # start of hardware interrupt (0x20).
outb %al, $0x21
call delay
movb $0x28, %al # start of hardware interrupt (0x28).
outb %al, $0xa1
call delay
movb $0x04, %al # set master.
outb %al, $0x21
call delay
movb $0x02, %al # set slave.
outb %al, $0xa1
call delay
movb $0x01, %al # 8086 mode.
outb %al, $0x21
call delay
outb %al, $0xa1
call delay
movb $0xff, %al # mask all.
outb %al, $0x21
call delay
outb %al, $0xa1
# Actually enter protected mode.
movw $0x0001, %ax
lmsw %ax
.byte 0x66, 0xea
code386:.long 0x10000
.word 8
kb_wait:
.word 0x00eb, 0x00eb # Dealy
inb $0x64, %al
testb $0x02, %al # Keyboard buffer is full?
jnz kb_wait # Yes, wait.
delay:
ret
secnum: .byte sectors - 1
read_kernel:
xorw %ax, %ax
xorw %dx, %dx
int $0x13
xorw %bx, %bx
movb $0x02, %ah
movb secnum, %al # %al == number of sectors
movw $0x0002, %cx # %ch == track number, %cl == sector number
movw $0x0000, %dx # %dh == head number, %dl == drive number
repeat_read:
call read_track
xorb %ah, %ah # al == number of sectors which have been read
shlw $9, %ax
addw %ax, %bx # %bx = %bx + (just read)
movw %bx, %ax # %ax = %bx
orw %ax, %ax # Is %ax == 0, if it's true, we have read 64K
je inc_es # just have read 64K, only %ax == 0, set CF
notw %ax # get the remaining size in one segment (64K).
incw %ax # the same as 64K - %ax.
shrw $9, %ax # unit from byte to 512 bytes.
cmpw $sectors, %ax # could the remaining size hold one track ?
jbe set_sector
movw $sectors, %ax
jmp set_sector
inc_es:
call print_dot
movw %es, %ax
addw $0x1000, %ax
cmpw $SYSEND, %ax
jae end_read
movw %ax, %es
movw $sectors, %ax
# %al contain the max secnum next time.
# %es : %bx, points the address next time. %cx, %dx, not being changed after
# read_track.
set_sector:
addb secnum, %cl # get the next sector to read
decb %cl # get the number of sectors being read
# within this track.
movb $sectors, secnum
subb %cl, secnum # get remaining sectors in track.
jne restore_cl # if remaining some, then not change head
# when reamining none, the set sector to 1, and change head
set_head_track:
movb $sectors, secnum # change head, so set secnum to max
movb $1, %cl # set sector
addb %dh, %ch # if head == 1, increment track
xorb $1, %dh # 0-->1, 1-->0
jmp set_secnum
restore_cl:
incb %cl
set_secnum:
cmpb secnum, %al # get the less
jb save_al
movb secnum, %al
jmp next
save_al:
movb %al, secnum
next:
movb $2, %ah
jmp repeat_read
end_read:
ret
print_dot:
pushw %ax
movw $0x0e2e, %ax
int $0x10
popw %ax
ret
read_track:
pushw %ax
pushw %bx
pushw %cx
pushw %dx
int $0x13 # all params have been prepared for.
jc reset_fd
popw %dx
popw %cx
popw %bx
popw %ax
ret
reset_fd:
xorw %ax, %ax
xorw %dx, %dx
int $0x13
popw %dx
popw %cx
popw %bx
popw %ax
jmp read_track
kill_motor:
movw $0x3f2, %dx
xorb %al, %al
outb %al, %dx
ret
gdt:
.word 0, 0, 0, 0
.word 0x07ff # limit == 8M (2048 * 4096)
.word 0x0000 # base address = 0
.word 0x9a00 # code read/exec
.word 0x00c0 # unit = 4096, 386
.word 0x07ff
.word 0x0000
.word 0x9200 # data read/write
.word 0x00c0
idt_pdesc:
.word 0
.word 0, 0
gdt_pdesc:
.word 8 * 3 - 1 # gdt limit = 24, 3 GDT entries
.word gdt + 0x7c00, 0
message:
.byte 0x0d, 0x0a
.ascii "Loading"
.org 510
.word 0xaa55

View File

@@ -0,0 +1,260 @@
# 1 "boot/boot.S"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "boot/boot.S"
BOOTSEG = 0x07c0
SYSSEG = 0x1000
SYSSIZE = 0x3000 # Max value may be 0x9000.
SYSEND = SYSSEG + SYSSIZE
# For 1.44M.
sectors = 18
.code16
.text
.global _start
_start:
movw $BOOTSEG, %ax
movw %ax, %ds
movw %ax, %es
cli
movw %ax, %ss
movw $0x8000, %sp # 0x8000 + 0x7c00 < 0x10000
sti
movb $3, %ah
xorb %bh, %bh
int $0x10
movw $0x1301, %ax
movw $0x0007, %bx
movw $message, %bp
movw $9, %cx
int $0x10
movw $SYSSEG, %ax
movw %ax, %es
call read_kernel
call kill_motor
# Save the current cursor at address 0x7c00 + 510, 0x7c00 + 511.
movb $3, %ah
xorb %bh, %bh
int $0x10
movw %dx, (510)
# Now it's time to enter protected mode.'
cli
lidt idt_pdesc
lgdt gdt_pdesc
# Enable a20.
call kb_wait
movb $0xd1, %al # command write.
outb %al, $0x64
call kb_wait
movb $0xdf, %al # enable a20.
outb %al, $0x60
call kb_wait
# Assume all things is ok. Go on to initialize 8259.
movb $0x11, %al # initialize sequence.
outb %al, $0x20
call delay
outb %al, $0xa0
call delay
movb $0x20, %al # start of hardware interrupt (0x20).
outb %al, $0x21
call delay
movb $0x28, %al # start of hardware interrupt (0x28).
outb %al, $0xa1
call delay
movb $0x04, %al # set master.
outb %al, $0x21
call delay
movb $0x02, %al # set slave.
outb %al, $0xa1
call delay
movb $0x01, %al # 8086 mode.
outb %al, $0x21
call delay
outb %al, $0xa1
call delay
movb $0xff, %al # mask all.
outb %al, $0x21
call delay
outb %al, $0xa1
# Actually enter protected mode.
movw $0x0001, %ax
lmsw %ax
.byte 0x66, 0xea
code386:.long 0x10000
.word 8
kb_wait:
.word 0x00eb, 0x00eb # Dealy
inb $0x64, %al
testb $0x02, %al # Keyboard buffer is full?
jnz kb_wait # Yes, wait.
delay:
ret
secnum: .byte sectors - 1
read_kernel:
xorw %ax, %ax
xorw %dx, %dx
int $0x13
xorw %bx, %bx
movb $0x02, %ah
movb secnum, %al # %al == number of sectors
movw $0x0002, %cx # %ch == track number, %cl == sector number
movw $0x0000, %dx # %dh == head number, %dl == drive number
repeat_read:
call read_track
xorb %ah, %ah # al == number of sectors which have been read
shlw $9, %ax
addw %ax, %bx # %bx = %bx + (just read)
movw %bx, %ax # %ax = %bx
orw %ax, %ax # Is %ax == 0, if it's true, we have read 64K'
je inc_es # just have read 64K, only %ax == 0, set CF
notw %ax # get the remaining size in one segment (64K).
incw %ax # the same as 64K - %ax.
shrw $9, %ax # unit from byte to 512 bytes.
cmpw $sectors, %ax # could the remaining size hold one track ?
jbe set_sector
movw $sectors, %ax
jmp set_sector
inc_es:
call print_dot
movw %es, %ax
addw $0x1000, %ax
cmpw $SYSEND, %ax
jae end_read
movw %ax, %es
movw $sectors, %ax
# %al contain the max secnum next time.
# %es : %bx, points the address next time. %cx, %dx, not being changed after
# read_track.
set_sector:
addb secnum, %cl # get the next sector to read
decb %cl # get the number of sectors being read
# within this track.
movb $sectors, secnum
subb %cl, secnum # get remaining sectors in track.
jne restore_cl # if remaining some, then not change head
# when reamining none, the set sector to 1, and change head
set_head_track:
movb $sectors, secnum # change head, so set secnum to max
movb $1, %cl # set sector
addb %dh, %ch # if head == 1, increment track
xorb $1, %dh # 0-->1, 1-->0
jmp set_secnum
restore_cl:
incb %cl
set_secnum:
cmpb secnum, %al # get the less
jb save_al
movb secnum, %al
jmp next
save_al:
movb %al, secnum
next:
movb $2, %ah
jmp repeat_read
end_read:
ret
print_dot:
pushw %ax
movw $0x0e2e, %ax
int $0x10
popw %ax
ret
read_track:
pushw %ax
pushw %bx
pushw %cx
pushw %dx
int $0x13 # all params have been prepared for.
jc reset_fd
popw %dx
popw %cx
popw %bx
popw %ax
ret
reset_fd:
xorw %ax, %ax
xorw %dx, %dx
int $0x13
popw %dx
popw %cx
popw %bx
popw %ax
jmp read_track
kill_motor:
movw $0x3f2, %dx
xorb %al, %al
outb %al, %dx
ret
gdt:
.word 0, 0, 0, 0
.word 0x07ff # limit == 8M (2048 * 4096)
.word 0x0000 # base address = 0
.word 0x9a00 # code read/exec
.word 0x00c0 # unit = 4096, 386
.word 0x07ff
.word 0x0000
.word 0x9200 # data read/write
.word 0x00c0
idt_pdesc:
.word 0
.word 0, 0
gdt_pdesc:
.word 8 * 3 - 1 # gdt limit = 24, 3 GDT entries
.word gdt + 0x7c00, 0
message:
.byte 0x0d, 0x0a
.ascii "Loading"
.org 510
.word 0xaa55

View File

@@ -0,0 +1,220 @@
/* head.S
* This code will check a20, and move itself from 0x10000 to 0x100000. Then
* setup idt table and gdt table, and set kernel page dir and kernel page table.
* But only low 8M is paged. After have done all things, it jump to main. This
* code still run under disabled interrupt.
*/
.text
.global idt, gdt, kp_dir
kp_dir:
.global on_journey
on_journey:
movl $0x10, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
xorl %eax, %eax
check_a20:
incl %eax
movl %eax, 0x000000
cmpl %eax, 0x100000
je check_a20
do_move:
cld
movl $0x24000, %ecx # max value is 0x90000 / 4
movl $0x10000, %esi
movl $0x100000, %edi
rep
movsl
movl $go_here, %eax
jmp *%eax
go_here:
lss stack_start, %esp
call setup_idt
call setup_gdt
movl $0x10, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
lss stack_start, %esp
# first we clear the screen
# cld
# movl $0x07200720, %eax
# movl $0xb8000, %edi
# movl $0x1000, %ecx # 4 x 0x1000 = 16K
# rep
# stosl
# update the cursor position, row = 0, col = 1
# movw $0x0, 0x7dfe
# movw $0x0, 0x7c00 + 510
# Then we will clear the bss region, set static var to 0
cld
movl $__bss_start, %edi
movl $_end, %ecx
subl %edi, %ecx # %ecx is the bss length
xorl %eax, %eax
rep
stosb
movl %cr0, %eax # check math chip
andl $0x80000011, %eax # save PG, ET, PE
# 31 4 3 2 1 0
# PG... ET TS EM MP PE
testl $0x10, %eax # ET is set if having 387
jne have_387
orl $0x04, %eax # emulate by software
have_387:
movl %eax, %cr0
setup_env_for_main:
pushl $0 # params for main
pushl $0
pushl $0
pushl $hang # ret addr for main
pushl $main
jmp setup_paging
# idt descriptor
# 7-6 5 - 4 3-2 1-0
# offset(31...16) Attributes sel offset(15...0)
setup_idt:
lea ignore_int, %edx
movl $0x00080000, %eax # sel = 0x0008 == cs
movw %dx, %ax
movw $0x8E00, %dx # interrupt gate - dpl = 0, present
# the high part in %edx contains ign...
movl $idt, %edi
movl $256, %ecx
rp_sidt:
movl %eax, (%edi)
movl %edx, 4(%edi)
addl $8, %edi
decl %ecx
jne rp_sidt
lidt idt_pdesc
ret
setup_gdt:
lgdt gdt_pdesc
ret
.align 2
idt_pdesc:
.word 256 * 8 - 1 # idt contains 256 entries
.long idt
.align 2
gdt_pdesc:
.word 256 * 8 - 1 # But I think we must large it.
.long gdt # Or only use one ldt and tss
# in our system.
# code in front of here will be ...
.org 0x1000
kp_0:
.org 0x2000
kp_1:
.org 0x3000
kp_2:
hang:
jmp hang
.align 2
ignore_int:
incb 0xb8000 + 160 # put something on the screen
movb $2, 0xb8000 + 161 # this would let us know something
iret # happened
setup_paging:
cld
movl $kp_dir, %edi
xorl %eax, %eax
movl $1024 * 3, %ecx
rep
stosl
movl $kp_0 + 7, kp_dir
movl $kp_1 + 7, kp_dir + 4
movl $kp_1 + 4092, %edi
movl $0x007ff007, %eax # 8M - 4096 + 7 (r/w u/s, p)
std
fill_pg:
stosl
subl $0x1000, %eax
jge fill_pg
movl $kp_dir, %eax
movl %eax, %cr3
movl %cr0, %eax
orl $0x80000000, %eax
movl %eax, %cr0
ret
.align 8
idt:
.fill 256, 8, 0
.align 8
gdt:
.word 0, 0, 0, 0
# kernel cs 0x08
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0x9a00
.word 0x00c0
# kernel ds 0x10
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0x9200
.word 0x00c0
# user cs 0x1b
# .word 0x3fff # base: 64M, limit: 64M
# .word 0x0000
# .word 0xfa00
# .word 0x04c0
# user ds 0x23
# .word 0x3fff # base: 64M, limit: 64M
# .word 0x0000
# .word 0xf200
# .word 0x04c0
# only for testing shell, signal, will be deleted
# user cs 0x1b
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0xfa00
.word 0x00c0
# user ds 0x23
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0xf200
.word 0x00c0
# tss descriptor
.word 0, 0, 0, 0
# for ldt, one each process
.fill 250, 8, 0 # not necessary to have so many

View File

@@ -0,0 +1,224 @@
# 1 "boot/head.S"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "boot/head.S"
.text
.global idt, gdt, kp_dir
kp_dir:
.global on_journey
on_journey:
movl $0x10, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
xorl %eax, %eax
check_a20:
incl %eax
movl %eax, 0x000000
cmpl %eax, 0x100000
je check_a20
do_move:
cld
movl $0x24000, %ecx # max value is 0x90000 / 4
movl $0x10000, %esi
movl $0x100000, %edi
rep
movsl
movl $go_here, %eax
jmp *%eax
go_here:
lss stack_start, %esp
call setup_idt
call setup_gdt
movl $0x10, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
lss stack_start, %esp
# first we clear the screen
# cld
# movl $0x07200720, %eax
# movl $0xb8000, %edi
# movl $0x1000, %ecx # 4 x 0x1000 = 16K
# rep
# stosl
# update the cursor position, row = 0, col = 1
# movw $0x0, 0x7dfe
# movw $0x0, 0x7c00 + 510
# Then we will clear the bss region, set static var to 0
cld
movl $__bss_start, %edi
movl $_end, %ecx
subl %edi, %ecx # %ecx is the bss length
xorl %eax, %eax
rep
stosb
movl %cr0, %eax # check math chip
andl $0x80000011, %eax # save PG, ET, PE
# 31 4 3 2 1 0
# PG... ET TS EM MP PE
testl $0x10, %eax # ET is set if having 387
jne have_387
orl $0x04, %eax # emulate by software
have_387:
movl %eax, %cr0
setup_env_for_main:
pushl $0 # params for main
pushl $0
pushl $0
pushl $hang # ret addr for main
pushl $main
jmp setup_paging
# idt descriptor
# 7-6 5 - 4 3-2 1-0
# offset(31...16) Attributes sel offset(15...0)
setup_idt:
lea ignore_int, %edx
movl $0x00080000, %eax # sel = 0x0008 == cs
movw %dx, %ax
movw $0x8E00, %dx # interrupt gate - dpl = 0, present
# the high part in %edx contains ign...
movl $idt, %edi
movl $256, %ecx
rp_sidt:
movl %eax, (%edi)
movl %edx, 4(%edi)
addl $8, %edi
decl %ecx
jne rp_sidt
lidt idt_pdesc
ret
setup_gdt:
lgdt gdt_pdesc
ret
.align 2
idt_pdesc:
.word 256 * 8 - 1 # idt contains 256 entries
.long idt
.align 2
gdt_pdesc:
.word 256 * 8 - 1 # But I think we must large it.
.long gdt # Or only use one ldt and tss
# in our system.
# code in front of here will be ...
.org 0x1000
kp_0:
.org 0x2000
kp_1:
.org 0x3000
kp_2:
hang:
jmp hang
.align 2
ignore_int:
incb 0xb8000 + 160 # put something on the screen
movb $2, 0xb8000 + 161 # this would let us know something
iret # happened
setup_paging:
cld
movl $kp_dir, %edi
xorl %eax, %eax
movl $1024 * 3, %ecx
rep
stosl
movl $kp_0 + 7, kp_dir
movl $kp_1 + 7, kp_dir + 4
movl $kp_1 + 4092, %edi
movl $0x007ff007, %eax # 8M - 4096 + 7 (r/w u/s, p)
std
fill_pg:
stosl
subl $0x1000, %eax
jge fill_pg
movl $kp_dir, %eax
movl %eax, %cr3
movl %cr0, %eax
orl $0x80000000, %eax
movl %eax, %cr0
ret
.align 8
idt:
.fill 256, 8, 0
.align 8
gdt:
.word 0, 0, 0, 0
# kernel cs 0x08
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0x9a00
.word 0x00c0
# kernel ds 0x10
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0x9200
.word 0x00c0
# user cs 0x1b
# .word 0x3fff # base: 64M, limit: 64M
# .word 0x0000
# .word 0xfa00
# .word 0x04c0
# user ds 0x23
# .word 0x3fff # base: 64M, limit: 64M
# .word 0x0000
# .word 0xf200
# .word 0x04c0
# only for testing shell, signal, will be deleted
# user cs 0x1b
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0xfa00
.word 0x00c0
# user ds 0x23
.word 0x3fff # base: 0, limit: 64M
.word 0x0000
.word 0xf200
.word 0x00c0
# tss descriptor
.word 0, 0, 0, 0
# for ldt, one each process
.fill 250, 8, 0 # not necessary to have so many

View File

@@ -0,0 +1,29 @@
AS = as
LD = ld
CC = gcc
CFLAGS = -Wall -O2 -fstrength-reduce -ofomit-frame-pointer \
-finline-functions -nostdinc -I../include
OBJS = timer.o keyboard.o ide.o vga.o
all: driver.o
driver.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
timer.o: timer.c
$(CC) $(CFLAGS) -c $< -o $@
keryboard.o: keyboard.c
$(CC) $(CFLAGS) -c $< -o $@
ide.o: ide.c
$(CC) $(CFLAGS) -c $< -o $@
vga.o: vga.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,198 @@
/* the simple ide disk drive for cnix,it is bug about disk order,I use the default first master
* disk for the pc.if your pc isn't the configuer ,it will error! I default hda! the support the
* one time extended partition!
*/
#include <asm/io.h>
#include <cnix/ide.h>
#include <cnix/partition.h>
#include <string.h>
#define ide_io_read(port,buf,nr) \
__asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr))
#define ide_io_write(port,buf,nr) \
__asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr))
ide_stutas_ok()
{
while(inb(HD_STATUS) & BUSY_STAT){
delay_50ms();
}
}
#define READ_CMD 0x20
lba_read_sector(long sector,unsigned char *buf)
{
int c,h,s;
s = sector &0xff;
c = (sector &0xffff00)>>8;
h = (sector &0xf000000)>>24;
outb(1,HD_NSECTOR);
outb(s,HD_SECTOR);
outb(c,HD_LCYL);
outb(c>>8,HD_HCYL);
/*the master disk*/
outb(0xE0|(0<<4)|h,HD_CURRENT);
outb(READ_CMD,HD_COMMAND);
ide_stutas_ok();
ide_io_read(HD_DATA,buf,256);
}
/*cnix don't used the read mode */
ide_chs_read(int c,int h,int s,unsigned char *buf)
{
/* the new ide have not the attrib
outb(_WPCOM,HD_ERROR);
*/
/*READ sector data,the asmcos default=1*/
outb(1,HD_NSECTOR);
outb(s,HD_SECTOR);
outb(c,HD_LCYL);
outb(c>>8,HD_HCYL);
/*the master disk*/
outb(0xA0|(0<<4)|h,HD_CURRENT);
outb(READ_CMD,HD_COMMAND);
ide_stutas_ok();
ide_io_read(HD_DATA,buf,256);
}
get_ide_info()
{
int status;
hd_driveid id;
unsigned short *ver_add;
unsigned char *disk_add;
unsigned int cyl;
unsigned char head;
unsigned int sect;
unsigned int ver_cs,ver_offset,ver_line;
outb(0xa0,HD_CURRENT);
outb(0xec,HD_STATUS);
while(inb(HD_STATUS)&0x80);
ide_io_read(HD_DATA,&id,256);
/*bios C/H/S */
ver_add = 0x104;
ver_offset = ver_add[0];
ver_cs = ver_add[1];
ver_line= ver_cs*0x10 + ver_offset;
disk_add = ver_line;
cyl = (disk_add[1]<<8)+disk_add[0];
head = disk_add[2];
sect = disk_add[14];
/*lba mode*/
cyl = id.lba_capacity /(head*sect) ;
printk("Your disk C:%d,H:%d,S:%d,LBA:%d\n",cyl,head,sect,id.lba_capacity);
}
/*start for get partition info*/
struct disk_partition part_p[8]; /*primary*/
get_partition()
{
int i;
unsigned char st_sector[512];
lba_read_sector(0,st_sector);
for(i=0;i<4;i++){
memcpy(&part_p[i].part.boot_ind,&st_sector[0x1be + 16*i],16);
memcpy(part_p[i].name,"hda",3);
part_p[i].name[3]=i+0x31;
}
find_extended_part();
}
#define DOS_EXT 0x5
#define CHS_EXT 0xf
#define LINUX_EXT 0x85
#define EXT2_PART 0x83
int find_extended_part()
{
unsigned char buf[512];
int i;
for(i=0;i<4;i++){
switch(part_p[i].part.sys_ind)
{
case DOS_EXT:
case CHS_EXT:
case LINUX_EXT:
lba_read_sector(part_p[i].part.start_sect,buf);
break;
default:
break;
}
}
for(i=0;i<4;i++){
memcpy(&part_p[i+4].part.boot_ind,&buf[0x1be + 16*i],16);
memcpy(part_p[i+4].name,"hda",3);
part_p[i+4].name[3]=i+0x35;
}
}
const char *
get_sysname(unsigned char type) {
struct systypes *s;
for (s = sys_types; s->type<0xff; s++)
if (s->type == type)
return s->name;
return "Unknown,wait you add";
}
print_part(struct disk_partition *part_p)
{
int enable;
int i;
char *part_type;
if (part_p->part.sys_ind ==0) return;
part_type = get_sysname(part_p->part.sys_ind);
enable = (part_p->part.boot_ind &0x80)>>1;
printk("%s:\n",part_p->name);
printk("Filesystem type ID:%s\n",part_type);
printk("Size :%d!Mb\n\n",part_p->part.nr_sects/2048);
}
print_part_list()
{
int i;
for(i=0;i<8;i++)
print_part(&part_p[i]);
}
ide_init()
{
get_ide_info();
}

View File

@@ -0,0 +1,437 @@
#include <tty.h>
#include <asm/io.h>
#include <cnix/sched.h>
#define DEBUG 0
static unsigned char e0;
static unsigned char mode = 0;
static unsigned char leds;
static unsigned char shift_map[] = {
0,27,
'!','@','#','$','%','^','&','*','(',')','_','+',
127,9
,'Q','W','E','R','T','Y','U','I','O','P','{','}',
10,0,
'A','S','D','F','G','H','J','K','L',':','"',
0,0
,'|','Z','X','C','V','B','N','M','<','>','?',
0,'\'','*',0,32, /* 36-39 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3A-49 */
'-',0,0,0,'+', /* 4A-4E */
0,0,0,0,0,0,0 /* 4F-55 */
,'>',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static unsigned char key_map[] = {
0,27,
'1','2','3','4','5','6','7','8','9','0','-','=',
127,9,
'q','w','e','r','t','y','u','i','o','p','[',
0,10,0,
'a','s','d','f','g','h','j','k','l',';','\'',
0,0,
'\\','z','x','c','v','b','n','m',',','.','/',
0,'*',0,32, /* 36-39 */
16,1,0 , /* 3A-49 */
'-',0,0,0,'+', /* 4A-4E */
0,0,0,0,0,0,0, /* 4F-55 */
'<',
10,1,0
};
static unsigned char alt_map[] = {
0,0,
0,'@',0,'$',0,0,'{','[',']','}','\\',0,
0,0,
0,0,0,0,0,0,0,0,0,0,0,
'~',10,0,
0,0,0,0,0,0,0,0,0,0,0,
0,0,
0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0, /* 36-39 */
16,1,0, /* 3A-49 */
0,0,0,0,0, /* 4A-4E */
0,0,0,0,0,0,0, /* 4F-55 */
'|',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static long func_table[] = {
0x415b5b1b,0x425b5b1b,0x435b5b1b,0x445b5b1b,
0x455b5b1b,0x465b5b1b,0x475b5b1b,0x485b5b1b,
0x495b5b1b,0x4a5b5b1b,0x4b5b5b1b,0x4c5b5b1b
};
static int do_self(int scancode);
static int uncaps(int scancode);
static int caps(int scancode);
static int lshift(int scancode);
static int rshift(int scancode);
static int unctrl(int scancode);
static int ctrl(int scancode);
static int none(int scancode);
static int num(int scancode);
static int minus(int scancode);
static int cursor(int scancode);
static int func(int scancode);
static int scroll(int scancode);
static int alt(int scancode);
static int unalt(int scancode);
static int unlshift(int scancode);
static int unrshift(int scancode);
static int setleds();
static int put_queue(long);
static int kbd_wait();
int reboot();
/* extern struct tty_quenue * table_list[6]; */
extern struct tty_queue read_q;
extern int do_tty_interrupt(int);
#define SIZE 64
typedef int (*keyfn_ptr)();
static keyfn_ptr key_tab[] = {
none,do_self,do_self,do_self /* 00-03 s0 esc 1 2 */
, do_self,do_self,do_self,do_self /* 04-07 3 4 5 6 */
, do_self,do_self,do_self,do_self /* 08-0B 7 8 9 0 */
, do_self,do_self,do_self,do_self /* 0C-0F + ' bs tab */
, do_self,do_self,do_self,do_self /* 10-13 q w e r */
, do_self,do_self,do_self,do_self /* 14-17 t y u i */
, do_self,do_self,do_self,do_self /* 18-1B o p } ^ */
, do_self,ctrl,do_self,do_self /* 1C-1F enter ctrl a s */
, do_self,do_self,do_self,do_self /* 20-23 d f g h */
, do_self,do_self,do_self,do_self /* 24-27 j k l | */
, do_self,do_self,lshift,do_self /* 28-2B { para lshift , */
, do_self,do_self,do_self,do_self /* 2C-2F z x c v */
, do_self,do_self,do_self,do_self /* 30-33 b n m , */
, do_self,minus,rshift,do_self /* 34-37 . - rshift * */
, alt,do_self,caps,func /* 38-3B alt sp caps f1 */
, func,func,func,func /* 3C-3F f2 f3 f4 f5 */
, func,func,func,func /* 40-43 f6 f7 f8 f9 */
, func,num,scroll,cursor /* 44-47 f10 num scr home */
, cursor,cursor,do_self,cursor /* 48-4B up pgup - left */
, cursor,cursor,do_self,cursor /* 4C-4F n5 right + end */
, cursor,cursor,cursor,cursor /* 50-53 dn pgdn ins del */
, none,none,do_self,func /* 54-57 sysreq ? < f11 */
, func,none,none,none /* 58-5B f12 ? ? ? */
, none,none,none,none /* 5C-5F ? ? ? ? */
, none,none,none,none /* 60-63 ? ? ? ? */
, none,none,none,none /* 64-67 ? ? ? ? */
, none,none,none,none /* 68-6B ? ? ? ? */
, none,none,none,none /* 6C-6F ? ? ? ? */
, none,none,none,none /* 70-73 ? ? ? ? */
, none,none,none,none /* 74-77 ? ? ? ? */
, none,none,none,none /* 78-7B ? ? ? ? */
, none,none,none,none /* 7C-7F ? ? ? ? */
, none,none,none,none /* 80-83 ? br br br */
, none,none,none,none /* 84-87 br br br br */
, none,none,none,none /* 88-8B br br br br */
, none,none,none,none /* 8C-8F br br br br */
, none,none,none,none /* 90-93 br br br br */
, none,none,none,none /* 94-97 br br br br */
, none,none,none,none /* 98-9B br br br br */
, none,unctrl,none,none /* 9C-9F br unctrl br br */
, none,none,none,none /* A0-A3 br br br br */
, none,none,none,none /* A4-A7 br br br br */
, none,none,unlshift,none /* A8-AB br br unlshift br */
, none,none,none,none /* AC-AF br br br br */
, none,none,none,none /* B0-B3 br br br br */
, none,none,unrshift,none /* B4-B7 br br unrshift br */
, unalt,none,uncaps,none /* B8-BB unalt br uncaps br */
, none,none,none,none /* BC-BF br br br br */
, none,none,none,none /* C0-C3 br br br br */
, none,none,none,none /* C4-C7 br br br br */
, none,none,none,none /* C8-CB br br br br */
, none,none,none,none /* CC-CF br br br br */
, none,none,none,none /* D0-D3 br br br br */
, none,none,none,none /* D4-D7 br br br br */
, none,none,none,none /* D8-DB br ? ? ? */
, none,none,none,none /* DC-DF ? ? ? ? */
, none,none,none,none /* E0-E3 e0 e1 ? ? */
, none,none,none,none /* E4-E7 ? ? ? ? */
, none,none,none,none /* E8-EB ? ? ? ? */
, none,none,none,none /* EC-EF ? ? ? ? */
, none,none,none,none /* F0-F3 ? ? ? ? */
, none,none,none,none /* F4-F7 ? ? ? ? */
, none,none,none,none /* F8-FB ? ? ? ? */
, none,none,none,none /* FC-FF ? ? ? ? */
} ;
static unsigned char num_tab[] = { '7','8','9',' ','4','5','6',' ','1','2','3','0'};
static unsigned char cur_tab[] = "HA5 DGC YB623" ;
static int code ;
int kbd_interrupt()
{
code = inb_p(0x60);
#if DEBUG
printk("%x ",code);
#endif
if ( code == 0xe0 )
e0 = 1;
else if ( code == 0xe1 )
e0 = 2;
else {
keyfn_ptr funp;
funp = key_tab[code];
funp(code) ;
e0 = 0;
}
outb_p((inb_p(0x61))|0x80,0x61);
outb_p((inb_p(0x61))&0x7f,0x61);
do_tty_interrupt(0);
return 0; /* avoid warning */
}
int do_self(int scancode)
{
char *map;
unsigned char ch;
int shftflg = 0 ; /* shift key is not pressed */
if (mode & 0x20 ) /* alt */
map = alt_map;
else if ( (mode & 0x3) ){ /* shift ^ caps */
map = shift_map;
shftflg = 1;
}
else map = key_map;
ch = map[scancode & 0xff];
#if DEBUG
printk("%c\t",ch);
#endif
if ( ch == 0) return 0;
if ((mode & 0x4c)){ /* ctrl or caps */
if ((ch <= 'z' && ch >= 'a' )) /* caps lower*/
ch -= 0x20 ; /* to upper */
if (mode & 0xc) /* ctrl */
ch -= 0x40; /* to ctrl ascii */
}
if (mode & 0x10)
ch |= 0x80 ; /* alt */
ch &= 0xff;
put_queue(ch);
return 0; /* avoid warning */
}
int alt(int scancode)
{
if ( e0) /* right ctrl */
mode |= 0x20;
else
mode |= 0x10;
return 0;
}
int unalt(int scancode)
{
if (e0)
mode &= 0xdf;
else
mode &= 0xef;
return 0;
}
int ctrl(int scancode)
{
if ( e0)
mode |= 0x8;
else
mode |= 0x4;
return 0;
}
int unctrl(int scancode)
{
if ( e0)
mode &= 0xF7;
else
mode &= 0xFB;
return 0;
}
int lshift(int scancode)
{
mode |= 0x1;
return 0;
}
int rshift(int scancode)
{
mode |= 0x2;
return 0;
}
int unlshift(int scancode)
{
mode &= 0xfe;
return 0;
}
int unrshift(int scancode)
{
mode &= 0xfd;
return 0;
}
int caps(int scancode)
{
if (!(mode & 0x80)){
leds ^= 0x4;
mode ^= 0x40;
mode |= 0x80;
setleds();
}
return 0;
}
int uncaps(int scancode)
{
mode &= 0x7f;
return 0;
}
int srcoll(int scancode)
{
leds |= 0x1;
setleds();
return 0;
}
int num(int scancode)
{
leds ^= 0x2;
setleds();
return 0;
}
int cursor(int scancode)
{
int i;
i = code - 0x47 ; /* cursor start with 71 */
if ( i < 0 || i > 12) return 0;
if ( i == 12 && (mode & 0xc ) && (mode & 0x30)) /* alt + ctrl + del */
reboot();
if ((e0 == 1 && !(leds & 0x2))|| (mode &0x3)){ /* num is not on and extends code or */
int ch;
ch = cur_tab[i];
if ( ch <= '9' ) ch ='~';
ch = ch<<16|0x5b1b; /* arrow direction */
put_queue(ch);
} else { /* leds is on , is num . this is not sure !!!! */
int ch;
ch = num_tab[i];
put_queue(ch);
}
return 0;
}
int func(int scancode)
{
int i = scancode - 59; /* function key starts from 59 */
if ( i >= 0 && i <= 11) { /* 12 function keys */
long ch ;
ch = func_table[i];
put_queue(ch);
}
return 0;
}
int minus (int scancode)
{
if ( e0 != 1)
do_self(scancode);
else
put_queue((long)'/');
return 0;
}
int setleds()
{
kbd_wait();
outb(0xed,0x60);
kbd_wait();
outb(leds,0x60);
return 0;
}
int kbd_wait()
{
while (inb_p(0x64) & 0x2) /* kbd in buffer is full */
/* do nothing */ ;
return 0;
}
int reboot()
{
kbd_wait();
outb(0xfc,0x64); /* reset system*/
while (1) ;
return 0;
}
int none(int scancode)
{
return 0;
}
int scroll(int scancode)
{
leds ^= 0x1;
setleds();
return 0;
}
static int put_queue(long ch)
{
struct tty_queue * q = &read_q;
while(ch){
(q->buf)[q->head] = ch &0xff;
#if DEBUG
printk("%c", ch&0xff);
#endif
q->head = (q->head +1)&(SIZE -1);
if ( q->head == q->tail ) /* buf is full */
return 0;
ch >>= 8;
}
/*
if ((long)q->proc_list != '\0')
(q->proc_list)->state = 0;
*/
return 0;
}

View File

@@ -0,0 +1,162 @@
#include <asm/io.h>
#include <asm/cmos.h>
#include <asm/system.h>
#include <cnix/sched.h>
#define HZ 100
#define LATCH (1193182/HZ)
struct bios_time{
int second;
int minute;
int hour;
int day;
int month;
int year;
int century;
};
/* fn_t is defined in sched.h. */
extern int put_irq_handler(int irq, fn_t fn);
extern void schedule(void);
long volatile timer_count;
long volatile boot_time;
struct bios_time bios_time;
/*delay 50 ms by asmcos*/
delay_50ms()
{
int time_delay;
time_delay = timer_count;
while((timer_count - time_delay ) < 6);
}
/*delay a second by asmcos*/
delay_s(int second)
{
int i;
for(i=0;i<20 *second;i++)
delay_50ms();
}
/* do some computing, and ..., struct regs_t */
static void do_timer(void)
{
int hour, minute, second, seconds;
unsigned char *vid_ptr = (unsigned char *)0xb8000 + 144;
seconds = bios_time.hour * 3600 + bios_time.minute * 60 +
bios_time.second + (timer_count / HZ);
hour = (seconds / 3600) % 24;
minute = (seconds % 3600) / 60;
second = seconds % 60;
BIN_TO_BCD(hour); BIN_TO_BCD(minute); BIN_TO_BCD(second);
*vid_ptr++ = ((hour >> 4) & 0x0f) + '0';
*vid_ptr++ = 0x04;
*vid_ptr++ = (hour & 0x0f) + '0';
*vid_ptr++ = 0x04;
*vid_ptr++ = ':';
*vid_ptr++ = 0x04;
*vid_ptr++ = ((minute >> 4) & 0x0f) + '0';
*vid_ptr++ = 0x04;
*vid_ptr++ = (minute & 0x0f) + '0';
*vid_ptr++ = 0x04;
*vid_ptr++ = ':';
*vid_ptr++ = 0x04;
*vid_ptr++ = ((second >> 4) & 0x0f) + '0';
*vid_ptr++ = 0x04;
*vid_ptr++ = (second & 0x0f) + '0';
*vid_ptr++ = 0x04;
timer_count++;
/* Now do something really useful. */
if(current != &(init_task.task))
if(current->counter)
current->counter--;
else
current->need_sched = 1;
}
#define MINUTE 60
#define HOUR (MINUTE * 60)
#define DAY (HOUR * 24)
#define YEAR (DAY * 365)
/* the months of leap year */
static int month[12] = {
0,
DAY * (31),
DAY * (31 + 29),
DAY * (31 + 29 + 31),
DAY * (31 + 29 + 31 + 30),
DAY * (31 + 29 + 31 + 30 + 31),
DAY * (31 + 29 + 31 + 30 + 31 + 30),
DAY * (31 + 29 + 31 + 30 + 31 + 30 + 31),
DAY * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31),
DAY * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
DAY * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
DAY * (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30),
};
static long time_to_second(struct bios_time * time)
{
long ret;
int year;
/* this century is 1 less than what we offen think of */
year = time->year + time->century * 100 - 1970;
/* 1972 % 4 == 0, 1973 - 1970 == 3, 3 + 1 == 4 */
ret = year * YEAR + DAY * ((year + 1) / 4);
ret += month[time->month - 1];
/* if it's not leap year */
if(time->month > 2 && ((year + 2) % 4))
ret -= DAY;
ret += DAY * (time->day - 1);
ret += HOUR * time->hour;
ret += MINUTE * time->minute;
ret += time->second;
return ret;
}
timer_init()
{
bios_time.second = CMOS_READ(RTC_SECOND);
bios_time.minute = CMOS_READ(RTC_MINUTE);
bios_time.hour = CMOS_READ(RTC_HOUR);
bios_time.day = CMOS_READ(RTC_DAY_OF_MONTH);
bios_time.month = CMOS_READ(RTC_MONTH);
bios_time.year = CMOS_READ(RTC_YEAR);
bios_time.century = CMOS_READ(RTC_CENTURY);
BCD_TO_BIN(bios_time.second); BCD_TO_BIN(bios_time.minute);
BCD_TO_BIN(bios_time.hour); BCD_TO_BIN(bios_time.day);
BCD_TO_BIN(bios_time.month); BCD_TO_BIN(bios_time.year);
BCD_TO_BIN(bios_time.century);
boot_time = time_to_second(&bios_time);
printk("Boot time: %u\n", boot_time);
printk("Century %d Year %02d Month %02d Day %02d Time: %02d : %02d : %02d\n",
bios_time.century,
bios_time.year, bios_time.month,
bios_time.day, bios_time.hour,
bios_time.minute, bios_time.second);
timer_count = 0; /* initilize */
/* set timer rate */
outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */
outb(LATCH & 0xff, 0x40); /* LSB */
outb(LATCH >> 8, 0x40); /* MSB */
put_irq_handler(0x00, do_timer);
}

View File

@@ -0,0 +1,169 @@
#include <string.h>
#include <vga.h>
#include <tty.h>
#include <asm/io.h>
#include <asm/system.h>
#include <cnix/wait.h>
#define VGA_CRT_INX 0x3d4
#define VGA_CRT_DATA 0x3d5
#define VID_MEM 0xb8000
#define lines 25
#define cols 80
extern kbd_interrupt();
unsigned char *vidmem;
static int pos;
static int cursor_x,cursor_y;
struct tty_queue read_q = { 0,0,""} ;/* head ,tail ,buf */
struct wait_queue * wait;
static inline void gotoxy(unsigned int x, unsigned int y);
static void scroll_up()
{
int i;
unsigned char * vidptr;
memcpy ( VID_MEM, VID_MEM + cols * 2, ( lines - 1 ) * cols * 2 );
vidptr = (unsigned char *)(VID_MEM + (lines - 1) * cols * 2);
for (i = 0; i < cols * 2; i += 2)
vidptr[i] = ' ';
}
static inline void gotoxy(unsigned int x,unsigned int y)
{
pos =( cols * y +x) * 2;
cli();
outb(14, VGA_CRT_INX);
outb(0xff & (pos >> 9), VGA_CRT_DATA);
outb(15, VGA_CRT_INX);
outb(0xff & (pos >> 1), VGA_CRT_DATA);
sti();
cursor_x = x;
cursor_y = y;
}
void puts(char *s)
{
unsigned char c;
int x, y;
x = cursor_x;
y = cursor_y;
while ( ( c = *s++ ) != '\0' ) {
if ( c == '\n' ) {
x = 0;
if ( ++y >= lines ) { /* has gone to bottom of screen */
scroll_up();
y--;
}
} else {
vidmem [ ( x + cols * y ) * 2 ] = c;
if ( ++x >= cols ) {
x = 0;
if ( ++y >= lines ) {
scroll_up();
y--;
}
}
}
}
cursor_x = x;
cursor_y = y;
gotoxy(x,y);
}
void putchar(char c)
{
int x,y;
x = cursor_x;
y = cursor_y;
if ( c == '\n' ) { /* print next line */
x = 0;
if ( ++y >= lines ) { /* has gone to bottom of screen */
scroll_up();
y--;
}
} else {
vidmem [ ( x + cols * y ) * 2 ] = c;
if ( ++x >= cols ) {
x = 0;
if ( ++y >= lines ) {
scroll_up();
y--;
}
}
}
cursor_x = x;
cursor_y = y;
gotoxy(x,y);
}
void delchar()
{
int x,y;
x = cursor_x;
y = cursor_y;
if(x==0){
if (y==0);
else { x =80; y--;}
}else x--;
vidmem [ ( x + cols * y ) * 2 ] = 0x20;
cursor_x = x;
cursor_y = y;
gotoxy(x,y);
}
unsigned char getchar(void)
{
unsigned char ch;
if(read_q.tail == read_q.head)
sleep_on(&wait);
ch = read_q.buf[read_q.tail];
read_q.tail = (read_q.tail + 1) & (SIZE - 1);
return ch;
}
void do_tty_interrupt(int channel)
{
if(read_q.tail != read_q.head)
if(wait != NULL)
wakeup(&wait);
}
void vga_init()
{
int x, y;
unsigned char val;
x = *(unsigned char *)(0x7c00+510);
y = *(unsigned char *)(0x7c00+511);
x = 0, y++;
gotoxy(x,y);
vidmem = (char *)VID_MEM;
wait = NULL;
put_irq_handler(0x1,&kbd_interrupt);
}

View File

@@ -0,0 +1,20 @@
LD = ld
CC = gcc
CFLAGS = -Wall -O2 -fstrength-reduce -ofomit-frame-pointer \
-finline-functions -nostdinc -I../include
OBJS = super.o inode.o open.o
all: fs.o
fs.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
%.o%.c:
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.o
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,178 @@
#include <cnix/fs.h>
#include <cnix/ext2_fs.h>
extern struct cnix_ext2 cn_e2;
struct ext2_dir_entry_2 current_dir[20];
get_root_inode(char *buf)
{
int address;
char *filename;
int i=0,j;
struct ext2_dir_entry_2 *e2dir;
address = &buf[0];
e2dir = &buf[0];
while(e2dir->inode){
filename = &e2dir->name[0];
handler_dir(filename,e2dir->name_len,e2dir);
if( (e2dir->name_len%4) ==0)
address = address +8 + e2dir->name_len;
else address = address +8 + (e2dir->name_len /4 +1 )*4;
e2dir = address;
}
}
static int root_count=0;
handler_dir(char *filename,int name_len,struct ext2_dir_entry_2 *e2dir)
{
char tmp;
int i;
tmp = filename[name_len];
filename[name_len]='\0';
cn_e2.root_dir[root_count] = *e2dir;
for(i = 0;i<name_len+1;i++)
cn_e2.root_dir[root_count].name[i] = filename[i];
root_count ++;
filename[name_len] = tmp;
}
read_inode(int count,char *buf_1,struct ext2_inode *e2ino_1)
{
struct ext2_group_desc *e2gd;
struct ext2_inode *e2ino;
int group_block;
int offset_group_block;
unsigned char buf_gd[512];
unsigned char buf[512];
group_block = count /cn_e2.s_inodes_per_group;
offset_group_block = count % cn_e2.s_inodes_per_group;
group_block ++;
{
int offset_sector;
int offset_count;
int gd_offset;
/*find the group block at group describe position
* get the group bolck start inode table
*/
offset_sector = group_block / (512/32);
offset_count = group_block %(512/32);
if(cn_e2.block_size==2) gd_offset = 1;
else gd_offset = 0;
lba_read_sector(cn_e2.start_sect +(gd_offset+1)*cn_e2.block_size+offset_sector,buf_gd);
e2gd =&buf_gd[ (offset_count-1) *32 ];
}
#if 0
read_desc(group_block,buf,e2gd);
read_inode_offset(offset_group_block,e2gd->bg_inode_table,buf,e2ino);
#endif
{
int inode_block;
int offset;
int sector,offset_sector;
/*512/cn_e2.s_inode_size = count inode at per sector */
inode_block = offset_group_block / (cn_e2.block_size *(512/cn_e2.s_inode_size));
offset = offset_group_block % (cn_e2.block_size *(512/cn_e2.s_inode_size));
sector = offset /(512/cn_e2.s_inode_size);
offset_sector = (offset-1) % (512/cn_e2.s_inode_size);
lba_read_sector(cn_e2.start_sect +e2gd->bg_inode_table * cn_e2.block_size +inode_block*cn_e2.block_size+sector,buf);
e2ino = & buf[offset_sector * cn_e2.s_inode_size];
}
{ int i ;
for (i=0;i<15;i++)
e2ino_1->i_block[i]=e2ino->i_block[i];
}
e2ino_1->i_size = e2ino->i_size;
}
read_inode_offset(int count,unsigned long inode_table,char *buf,struct ext2_inode *e2ino)
{
int inode_block;
int offset;
int sector,offset_sector;
/*512/cn_e2.s_inode_size = count inode at per sector */
inode_block = count / (cn_e2.block_size*(512/cn_e2.s_inode_size));
offset = count % (cn_e2.block_size*(512/cn_e2.s_inode_size));
sector = offset /(512/cn_e2.s_inode_size);
offset_sector = (offset-1) % (512/cn_e2.s_inode_size);
lba_read_sector(cn_e2.start_sect +inode_table * cn_e2.block_size +inode_block*cn_e2.block_size+sector,buf);
e2ino = & buf[offset_sector * cn_e2.s_inode_size];
}
get_current_dir(char *buf)
{
int address;
char *filename;
int i=0,j;
struct ext2_dir_entry_2 *e2dir;
address = &buf[0];
e2dir = &buf[0];
while(e2dir->inode){
filename = &e2dir->name[0];
handler_current_dir(filename,e2dir->name_len,e2dir);
if( (e2dir->name_len%4) ==0)
address = address +8 + e2dir->name_len;
else address = address +8 + (e2dir->name_len /4 +1 )*4;
e2dir = address;
}
}
static int dir_count=0;
handler_current_dir(char *filename,int name_len,struct ext2_dir_entry_2 *e2dir)
{
char tmp;
int i;
tmp = filename[name_len];
filename[name_len]='\0';
current_dir[dir_count] = *e2dir;
for(i = 0;i<name_len+1;i++)
current_dir[dir_count].name[i] = filename[i];
dir_count ++;
filename[name_len] = tmp;
}

View File

@@ -0,0 +1,93 @@
#include <string.h>
#include <cnix/ext2_fs.h>
#include <cnix/cfile.h>
extern struct cnix_ext2 cn_e2;
extern struct ext2_dir_entry_2 current_dir[20];
struct cfile *
cnix_open(char *dir,char *filename,unsigned char *file_buf)
{
int i=0;
struct ext2_inode e2ino;
unsigned char buf[512];
struct cfile *file;
file = cnix_malloc(8);
while(cn_e2.root_dir[i].inode)
{
if(strncmp(cn_e2.root_dir[i].name,dir,strlen(dir))==0)
break;
i++;
}
read_inode(cn_e2.root_dir[i].inode,buf,&e2ino);
lba_read_sector(cn_e2.start_sect +e2ino.i_block[0] * cn_e2.block_size,buf);
get_current_dir(&buf);
i = 0;
while(current_dir[i].inode)
{
if(strncmp(current_dir[i].name,filename,strlen(filename))==0)
break;
i++;
}
read_inode(current_dir[i].inode,buf,&e2ino);
{
int i,j,file_block;
unsigned long file_long[256];
file_block = e2ino.i_size/512/cn_e2.block_size +1;
file_buf = cnix_malloc(file_block * cn_e2.block_size *512);
if (file_block <12) j = file_block;
else j = 12;
/*the 12 block*/
for(i=0;i<j*cn_e2.block_size;i++)
{
lba_read_sector(cn_e2.start_sect +e2ino.i_block[i/cn_e2.block_size] * cn_e2.block_size+i%cn_e2.block_size,file_buf+i*512);
}
/*for 2nd block*/
/*get the 2nd block bitmap table*/
if(file_block >12){
lba_read_sector(cn_e2.start_sect +e2ino.i_block[12] *cn_e2.block_size,file_long);
lba_read_sector(cn_e2.start_sect +e2ino.i_block[12] *cn_e2.block_size+1,&file_long[128]);
}
/*read the 2nd data*/
for(i=0;i<(file_block-12);i++)
{/*per block read*/
int off_j;
for(off_j=0;off_j<cn_e2.block_size;off_j++)
{/*per sector read*/
lba_read_sector(cn_e2.start_sect + file_long[i]*cn_e2.block_size+off_j,file_buf+12*512+i*cn_e2.block_size+off_j*512);
}
}
}
file->size = e2ino.i_size;
file->file_buf = file_buf;
return file;
#if 0
printk("filename:%s\n",filename);
printk(buf);
printk("\n");
#endif
}
print_hex(unsigned char *buf)
{
int j=0;
for(j=0;j<512;j++)
printk("%02x ",buf[j]);
printk("\n");
}

View File

@@ -0,0 +1,105 @@
#include <cnix/ext2_fs.h>
#include <cnix/partition.h>
#include <string.h>
extern void lba_read_sector(long sector,unsigned char *buf);
extern void get_partition(void);
extern struct disk_partition part_p[8];
struct partition *ext2_part;
char file_buf[100*512]; /*no malloc function to test my define 50k memory*/
struct cnix_ext2 cn_e2;
read_desc(int count,char *buf,struct ext2_group_desc *e2gd)
{
int offset_sector;
int offset_count;
/*find the group block at group describe position
* get the group bolck start inode table
*/
offset_sector = count / (512/32);
offset_count = count %(512/32);
lba_read_sector(cn_e2.start_sect +cn_e2.block_size+offset_sector,buf);
e2gd =&buf[ (offset_count-1) *32 ];
}
int
read_super(char *s)
{
unsigned char buf[512];
struct ext2_super_block *e2sb;
struct ext2_group_desc *e2gd;
struct ext2_inode e2ino;
struct ext2_inode e2ino_root;
struct ext2_dir_entry_2 *e2dir;
char *filename;
int block_size;
static int address= 0;
int i;
for(i=0;i<8;i++){
if(strcmp(s,&part_p[i].name)==0)
ext2_part =&part_p[i].part;
}
if(ext2_part->sys_ind!=0x83) return 0;
lba_read_sector(ext2_part->start_sect +2,buf); /*first sector is boot block ,so 2nd sector is super!*/
e2sb = &buf[0];
if(e2sb->s_magic == EXT2_SUPER_MAGIC )
printk("Find ext2 super block ok!\n");
else { printk("Can't find ext2 super block!\n"); return 0;}
block_size = 1<<e2sb->s_log_block_size ;/*fix by asmcos,thank xiexiecn*/
/*save the super block data to cnix ext2 for call*/
cn_e2.block_size = block_size *2;
cn_e2.s_blocks_per_group = e2sb->s_blocks_per_group;
cn_e2.s_inodes_per_group = e2sb->s_inodes_per_group;
cn_e2.s_inode_size = e2sb->s_inode_size;
cn_e2.start_sect = ext2_part->start_sect;
/*group describe table
* the boot and super block in 0 block
* the group describ table in 1 block
* the block size = n k(n = 1,2,4), = 2n sectors.
*/
read_inode(2,buf,&e2ino);
lba_read_sector(cn_e2.start_sect +e2ino.i_block[0] * cn_e2.block_size ,buf);
get_root_inode(&buf);
printk("Your root dir:\n");
{int i =0;
while(cn_e2.root_dir[i].inode)
{
print_fn(&cn_e2.root_dir[i].name);
i++;
}
printk("\n");
}
}
print_fn(char *filename)
{
printk("/");
printk("%s",filename);
printk(" ");
}
fs_init()
{
get_partition();
read_super("hda2");
}

View File

@@ -0,0 +1,37 @@
#ifndef CMOS_H
#define CMOS_H
#include <asm/io.h>
#define CMOS_READ(addr) ({\
outb_p(addr | 0x80, 0x70);\
inb_p(0x71);\
})
#define RTC_SECOND 0
#define RTC_SECOND_ALRAM 1
#define RTC_MINUTE 2
#define RTC_MINUTE_ALRAM 3
#define RTC_HOUR 4
#define RTC_HOUR_ALRAM 5
#define RTC_DAY_OF_WEEK 6
#define RTC_DAY_OF_MONTH 7
#define RTC_MONTH 8
#define RTC_YEAR 9
#define RTC_REG_A 10
#define RTC_REG_B 11
#define RTC_REG_C 12
#define RTC_REG_D 13
#define RTC_CENTURY 0x32
#ifndef BCD_TO_BIN
#define BCD_TO_BIN(val) (val = (val & 0x0f) + ((val >> 4) * 10))
#endif
#ifndef BIN_TOBCD
#define BIN_TO_BCD(val) (val = ((val / 10) << 4) + (val % 10))
#endif
#endif

View File

@@ -0,0 +1,29 @@
#ifndef IO_H
#define IO_H
#define outb(value,port) \
__asm__ ("outb %%al,%%dx"::"a" (value),"d" (port))
#define inb(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \
_v; \
})
#define outb_p(value,port) \
__asm__ ("outb %%al,%%dx\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:"::"a" (value),"d" (port))
#define inb_p(port) ({ \
unsigned char _v; \
__asm__ volatile ("inb %%dx,%%al\n" \
"\tjmp 1f\n" \
"1:\tjmp 1f\n" \
"1:":"=a" (_v):"d" (port)); \
_v; \
})
#endif

View File

@@ -0,0 +1,22 @@
#ifndef REGS_H
#define REGS_H
struct regs_t{
long ebx;
long ecx;
long edx;
long esi;
long edi;
long ebp;
long eax;
long ds;
long es; /* index of execption */
long index; /* index of interrupt, error of execption */
long eip;
long cs;
long eflags;
long esp;
long ss;
};
#endif

View File

@@ -0,0 +1,62 @@
#define sti() __asm__ ("sti"::)
#define cli() __asm__ ("cli"::)
#define nop() __asm__ ("nop"::)
#define iret() __asm__ ("iret"::)
#define save_flags(x) \
__asm__ __volatile__("pushfl\n\t" \
"popl %0\n\t" \
:"=g" (x)\
:)
#define restore_flags(x) \
__asm__ __volatile__("pushl %0\n\t" \
"popfl \n\t" \
: \
:"g" (x))
#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ ("movw %%dx,%%ax\n\t" \
"movw %0,%%dx\n\t" \
"movl %%eax,%1\n\t" \
"movl %%edx,%2" \
: \
: "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
"o" (*((char *) (gate_addr))), \
"o" (*(4+(char *) (gate_addr))), \
"d" ((char *) (addr)),"a" (0x00080000))
#define set_intr_gate(n,addr) \
_set_gate(&idt[n],14,0,addr)
#define set_trap_gate(n,addr) \
_set_gate(&idt[n],15,0,addr)
#define set_system_gate(n,addr) \
_set_gate(&idt[n],15,3,addr)
#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\
*(gate_addr) = ((base) & 0xff000000) | \
(((base) & 0x00ff0000)>>16) | \
((limit) & 0xf0000) | \
((dpl)<<13) | \
(0x00408000) | \
((type)<<8); \
*((gate_addr)+1) = (((base) & 0x0000ffff)<<16) | \
((limit) & 0x0ffff); }
#define _set_tss_desc(n,addr) \
__asm__ ("movw $104,%1\n\t" \
"movw %%ax,%2\n\t" \
"rorl $16,%%eax\n\t" \
"movb %%al,%3\n\t" \
"movb $0x89,%4\n\t" \
"movb $0x00,%5\n\t" \
"movb %%ah,%6\n\t" \
"rorl $16,%%eax" \
::"a" (addr), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \
"m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \
)
// first not think about IOmap
#define set_tss_desc(n,addr) _set_tss_desc(((char *) (n)),addr)

View File

@@ -0,0 +1,11 @@
#ifndef __CFILE_H__
#define __CFILE_H__
struct cfile{
int size;
unsigned char *file_buf;
};
#endif /*__CFILE_H__*/

View File

@@ -0,0 +1,8 @@
#ifndef CONFIG_H
#define CONFIG_H
#define HIGH_MEM 0x4000000
#define LOW_MEM 0x100000
#define DMA_HIGH_MEM 0x1000000
#endif

View File

@@ -0,0 +1,179 @@
#ifndef __EXT2_FS_H__
#define __EXT2_FS_H__
#define EXT2_SUPER_MAGIC 0xEF53
#define __u32 unsigned long
#define __s32 signed long
#define __s16 signed short
#define __u16 unsigned short
#define __u8 unsigned char
struct ext2_super_block {
__u32 s_inodes_count; /* Inodes count */
__u32 s_blocks_count; /* Blocks count */
__u32 s_r_blocks_count; /* Reserved blocks count */
__u32 s_free_blocks_count; /* Free blocks count */
__u32 s_free_inodes_count; /* Free inodes count */
__u32 s_first_data_block; /* First Data Block */
__u32 s_log_block_size; /* Block size */
__s32 s_log_frag_size; /* Fragment size */
__u32 s_blocks_per_group; /* # Blocks per group */
__u32 s_frags_per_group; /* # Fragments per group */
__u32 s_inodes_per_group; /* # Inodes per group */
__u32 s_mtime; /* Mount time */
__u32 s_wtime; /* Write time */
__u16 s_mnt_count; /* Mount count */
__s16 s_max_mnt_count; /* Maximal mount count */
__u16 s_magic; /* Magic signature */
__u16 s_state; /* File system state */
__u16 s_errors; /* Behaviour when detecting errors */
__u16 s_minor_rev_level; /* minor revision level */
__u32 s_lastcheck; /* time of last check */
__u32 s_checkinterval; /* max. time between checks */
__u32 s_creator_os; /* OS */
__u32 s_rev_level; /* Revision level */
__u16 s_def_resuid; /* Default uid for reserved blocks */
__u16 s_def_resgid; /* Default gid for reserved blocks */
/*
* These fields are for EXT2_DYNAMIC_REV superblocks only.
*
* Note: the difference between the compatible feature set and
* the incompatible feature set is that if there is a bit set
* in the incompatible feature set that the kernel doesn't
* know about, it should refuse to mount the filesystem.
*
* e2fsck's requirements are more strict; if it doesn't know
* about a feature in either the compatible or incompatible
* feature set, it must abort and not try to meddle with
* things it doesn't understand...
*/
__u32 s_first_ino; /* First non-reserved inode */
__u16 s_inode_size; /* size of inode structure */
__u16 s_block_group_nr; /* block group # of this superblock */
__u32 s_feature_compat; /* compatible feature set */
__u32 s_feature_incompat; /* incompatible feature set */
__u32 s_feature_ro_compat; /* readonly-compatible feature set */
__u8 s_uuid[16]; /* 128-bit uuid for volume */
char s_volume_name[16]; /* volume name */
char s_last_mounted[64]; /* directory where last mounted */
__u32 s_algorithm_usage_bitmap; /* For compression */
/*
* Performance hints. Directory preallocation should only
* happen if the EXT2_COMPAT_PREALLOC flag is on.
*/
__u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
__u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
__u16 s_padding1;
__u32 s_reserved[204]; /* Padding to the end of the block */
};
struct ext2_group_desc
{
__u32 bg_block_bitmap; /* Blocks bitmap block */
__u32 bg_inode_bitmap; /* Inodes bitmap block */
__u32 bg_inode_table; /* Inodes table block */
__u16 bg_free_blocks_count; /* Free blocks count */
__u16 bg_free_inodes_count; /* Free inodes count */
__u16 bg_used_dirs_count; /* Directories count */
__u16 bg_pad;
__u32 bg_reserved[3];
};
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
struct ext2_inode {
__u16 i_mode; /* File mode */
__u16 i_uid; /* Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* Creation time */
__u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
__u32 i_flags; /* File flags */
union {
struct {
__u32 l_i_reserved1;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
__u32 i_version; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
__u32 i_dir_acl; /* Directory ACL */
__u32 i_faddr; /* Fragment address */
union {
struct {
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__u32 l_i_reserved2[2];
} linux2;
struct {
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__u8 m_i_frag; /* Fragment number */
__u8 m_i_fsize; /* Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
#define EXT2_NAME_LEN 255
struct ext2_dir_entry {
__u32 inode; /* Inode number */
__u16 rec_len; /* Directory entry length */
__u16 name_len; /* Name length */
char name[EXT2_NAME_LEN]; /* File name */
};
struct ext2_dir_entry_2 {
__u32 inode; /* Inode number */
__u16 rec_len; /* Directory entry length */
__u8 name_len; /* Name length */
__u8 file_type;
char name[EXT2_NAME_LEN]; /* File name */
};
struct cnix_ext2 {
/*the super data save in memroy for cnix*/
__u32 start_sect; /*start sector*/
__u32 s_inodes_count; /* Inodes count */
__u32 s_blocks_count; /* Blocks count */
__u32 block_size; /* Block size for cnix is sector */
__s32 s_log_frag_size; /* Fragment size */
__u32 s_blocks_per_group; /* # Blocks per group */
__u32 s_frags_per_group; /* # Fragments per group */
__u32 s_inodes_per_group; /* # Inodes per group */
__u32 s_first_ino; /* First non-reserved inode */
__u16 s_inode_size; /* size of inode structure */
__u16 s_block_group_nr; /* block group # of this superblock */
/*the root inode data save in memroy*/
struct ext2_dir_entry_2 root_dir[20];
};
#endif /*__EXT2_FS_H__*/

View File

@@ -0,0 +1,54 @@
#ifndef FS_H
#define FS_H
#include <cnix/sched.h>
#define NR_HASH 50
#define NR_BUF ((160*0x1000 - 10*0x1000)/0x400)
#define BLOCKSIZ 0x400
#define NULL '\0'
#define NODEV 0
#define WRITE 0
#define READ 1
struct buf_head{
int b_dev;
int b_blocknr;
short int b_flags; /* buf state */
struct task_struct *b_wait;
unsigned char *b_data; /* point to the disk data in memory */
struct buf_head *b_next;
struct buf_head *b_prev;
struct buf_head *b_next_free;
struct buf_head *b_prev_free;
};
#define B_WRITE 0
#define B_READ 01
/* The buf is not in free list , only one proc can use it */
#define B_BUSY 02
/* delay write , The buf is different from disk ,so if release it ,you must write to disk */
#define B_DELWRI 04
/* disk io complete , the buf contains validated data */
#define B_DONE 010
#define B_WANTED 020 /* another proc want this buf , but it is busy , so the proc must sleep */
#define B_ERROR 040 /* the disk i/o has some errors , data can not be retrieve */
#define B_ASY 0100 /* asynchronize write or read ,not wait the io complicaton */
struct dinode {
int d_dev;
int d_inum;
int d_imode; /* which type of this file */
unsigned char d_ilock; /* d_ilock == 1 locked , d_ilock == 0 free */
};
extern struct buf_head * bread(int ,int);
extern void bwrite(struct buf_head *);
extern void iodone(struct buf_head *);
#endif

View File

@@ -0,0 +1,13 @@
#ifndef HEAD_H
#define HEAD_H
typedef struct desc_struct{
unsigned long a, b;
}desc_table[256];
extern unsigned long kp_dir[1024];
extern desc_table gdt, idt;
extern int end; /* edata, etext ..., I think need to clear bss or ... */
#endif

View File

@@ -0,0 +1,223 @@
#ifndef __IDE_H__
#define __IDE_H__
#define HD_DATA 0x1f0 /* _CTL when writing */
#define HD_ERROR 0x1f1 /* see err-bits */
#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
#define HD_SECTOR 0x1f3 /* starting sector */
#define HD_LCYL 0x1f4 /* starting cylinder */
#define HD_HCYL 0x1f5 /* high byte of starting cyl */
#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
#define HD_STATUS 0x1f7 /* see status-bits */
#define HD_PRECOMP HD_ERROR /* same io address, read=error, write=precomp */
#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */
#define HD_CMD 0x3f6
/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
#define ECC_STAT 0x04 /* Corrected error */
#define DRQ_STAT 0x08
#define SEEK_STAT 0x10
#define WRERR_STAT 0x20
#define READY_STAT 0x40
#define BUSY_STAT 0x80
typedef struct {
unsigned short config; /* lots of obsolete bit flags */
unsigned short cyls; /* "physical" cyls */
unsigned short reserved2; /* reserved (word 2) */
unsigned short heads; /* "physical" heads */
unsigned short track_bytes; /* unformatted bytes per track */
unsigned short sector_bytes; /* unformatted bytes per sector */
unsigned short sectors; /* "physical" sectors per track */
unsigned short vendor0; /* vendor unique */
unsigned short vendor1; /* vendor unique */
unsigned short vendor2; /* vendor unique */
unsigned char serial_no[20]; /* 0 = not_specified */
unsigned short buf_type;
unsigned short buf_size; /* 512 byte increments; 0 = not_specified */
unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */
unsigned char fw_rev[8]; /* 0 = not_specified */
unsigned char model[40]; /* 0 = not_specified */
unsigned char max_multsect; /* 0=not_implemented */
unsigned char vendor3; /* vendor unique */
unsigned short dword_io; /* 0=not_implemented; 1=implemented */
unsigned char vendor4; /* vendor unique */
unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/
unsigned short reserved50; /* reserved (word 50) */
unsigned char vendor5; /* vendor unique */
unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */
unsigned char vendor6; /* vendor unique */
unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */
unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */
unsigned short cur_cyls; /* logical cylinders */
unsigned short cur_heads; /* logical heads */
unsigned short cur_sectors; /* logical sectors per track */
unsigned short cur_capacity0; /* logical total sectors on drive */
unsigned short cur_capacity1; /* (2 words, misaligned int) */
unsigned char multsect; /* current multiple sector count */
unsigned char multsect_valid; /* when (bit0==1) multsect is ok */
unsigned int lba_capacity; /* total number of sectors */
unsigned short dma_1word; /* single-word dma info */
unsigned short dma_mword; /* multiple-word dma info */
unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */
unsigned short eide_dma_min; /* min mword dma cycle time (ns) */
unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */
unsigned short eide_pio; /* min cycle time (ns), no IORDY */
unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */
unsigned short word69;
unsigned short word70;
/* HDIO_GET_IDENTITY currently returns only words 0 through 70 */
unsigned short word71;
unsigned short word72;
unsigned short word73;
unsigned short word74;
unsigned short word75;
unsigned short word76;
unsigned short word77;
unsigned short word78;
unsigned short word79;
unsigned short word80;
unsigned short word81;
unsigned short command_sets; /* bits 0:Smart 1:Security 2:Removable 3:PM */
unsigned short word83; /* bits 14:Smart Enabled 13:0 zero */
unsigned short word84;
unsigned short word85;
unsigned short word86;
unsigned short word87;
unsigned short dma_ultra;
unsigned short word89; /* reserved (word 89) */
unsigned short word90; /* reserved (word 90) */
unsigned short word91; /* reserved (word 91) */
unsigned short word92; /* reserved (word 92) */
unsigned short word93; /* reserved (word 93) */
unsigned short word94; /* reserved (word 94) */
unsigned short word95; /* reserved (word 95) */
unsigned short word96; /* reserved (word 96) */
unsigned short word97; /* reserved (word 97) */
unsigned short word98; /* reserved (word 98) */
unsigned short word99; /* reserved (word 99) */
unsigned short word100; /* reserved (word 100) */
unsigned short word101; /* reserved (word 101) */
unsigned short word102; /* reserved (word 102) */
unsigned short word103; /* reserved (word 103) */
unsigned short word104; /* reserved (word 104) */
unsigned short word105; /* reserved (word 105) */
unsigned short word106; /* reserved (word 106) */
unsigned short word107; /* reserved (word 107) */
unsigned short word108; /* reserved (word 108) */
unsigned short word109; /* reserved (word 109) */
unsigned short word110; /* reserved (word 110) */
unsigned short word111; /* reserved (word 111) */
unsigned short word112; /* reserved (word 112) */
unsigned short word113; /* reserved (word 113) */
unsigned short word114; /* reserved (word 114) */
unsigned short word115; /* reserved (word 115) */
unsigned short word116; /* reserved (word 116) */
unsigned short word117; /* reserved (word 117) */
unsigned short word118; /* reserved (word 118) */
unsigned short word119; /* reserved (word 119) */
unsigned short word120; /* reserved (word 120) */
unsigned short word121; /* reserved (word 121) */
unsigned short word122; /* reserved (word 122) */
unsigned short word123; /* reserved (word 123) */
unsigned short word124; /* reserved (word 124) */
unsigned short word125; /* reserved (word 125) */
unsigned short word126; /* reserved (word 126) */
unsigned short word127; /* reserved (word 127) */
unsigned short security; /* bits 0:support 1:enabled 2:locked 3:frozen */
unsigned short reserved[127];
}hd_driveid;
struct systypes {
unsigned char type;
char *name;
} sys_types[] = {
{0, "Empty"},
{1, "DOS 12-bit FAT"}, /* Primary DOS with 12-bit FAT */
{2, "XENIX /"}, /* XENIX / filesystem */
{3, "XENIX /usr"}, /* XENIX /usr filesystem */
{4, "DOS 16-bit FAT <32M"}, /* Primary DOS with 16-bit FAT */
{5, "DOS Extended"}, /* DOS 3.3+ extended partition */
{6, "DOS 16-bit FAT >=32M"},
{7, "OS/2 IFS (e.g., HPFS) or NTFS or QNX2 or Advanced UNIX"},
{8, "AIX boot or SplitDrive"},
{9, "AIX data or Coherent"},
{0x0a, "OS/2 Boot Manager or Coherent swap"},
{0x0b, "Windows FAT32"},
{0x0c, "Windows FAT32 (lba)"},
{0x0d, "Windows FAT16(lba)"},
{0x0e, "DOS (16-bit FAT), CHS-mapped"},
{0x0f, "Ext. partition, CHS-mapped"},
{0x10, "OPUS"},
{0x11, "OS/2 BM: hidden DOS 12-bit FAT"},
{0x12, "Compaq diagnostics"},
{0x14, "OS/2 BM: hidden DOS 16-bit FAT <32M"},
{0x16, "OS/2 BM: hidden DOS 16-bit FAT >=32M"},
{0x17, "OS/2 BM: hidden IFS"},
{0x18, "AST Windows swapfile"},
{0x24, "NEC DOS"},
{0x3c, "PartitionMagic recovery"},
{0x40, "Venix 80286"},
{0x41, "Linux/MINIX (sharing disk with DRDOS)"},
{0x42, "SFS or Linux swap (sharing disk with DRDOS)"},
{0x43, "Linux native (sharing disk with DRDOS)"},
{0x50, "DM (disk manager)"},
{0x51, "DM6 Aux1 (or Novell)"},
{0x52, "CP/M or Microport SysV/AT"},
{0x53, "DM6 Aux3"},
{0x54, "DM6"},
{0x55, "EZ-Drive (disk manager)"},
{0x56, "Golden Bow (disk manager)"},
{0x5c, "Priam Edisk (disk manager)"}, /* according to S. Widlake */
{0x61, "SpeedStor"},
{0x63, "GNU HURD or Mach or Sys V/386 (such as ISC UNIX)"},
{0x64, "Novell Netware 286"},
{0x65, "Novell Netware 386"},
{0x70, "DiskSecure Multi-Boot"},
{0x75, "PC/IX"},
{0x77, "QNX4.x"},
{0x78, "QNX4.x 2nd part"},
{0x79, "QNX4.x 3rd part"},
{0x80, "MINIX until 1.4a"},
{0x81, "MINIX since 1.4b, early Linux, Mitac dmgr"},
{0x82, "Linux swap"},
{0x83, "Linux native"},
{0x84, "OS/2 hidden C: drive"},
{0x85, "Linux extended"},
{0x86, "NTFS volume set??"},
{0x87, "NTFS volume set??"},
{0x93, "Amoeba"},
{0x94, "Amoeba BBT"}, /* (bad block table) */
{0xa0, "IBM Thinkpad hibernation"}, /* according to dan@fch.wimsey.bc.ca */
{0xa5, "BSD/386"}, /* 386BSD */
{0xa7, "NeXTSTEP 486"},
{0xb7, "BSDI fs"},
{0xb8, "BSDI swap"},
{0xc1, "DRDOS/sec (FAT-12)"},
{0xc4, "DRDOS/sec (FAT-16, < 32M)"},
{0xc6, "DRDOS/sec (FAT-16, >= 32M)"},
{0xc7, "Syrinx"},
{0xdb, "CP/M or Concurrent CP/M or Concurrent DOS or CTOS"},
{0xe1, "DOS access or SpeedStor 12-bit FAT extended partition"},
{0xe3, "DOS R/O or SpeedStor"},
{0xe4, "SpeedStor 16-bit FAT extended partition < 1024 cyl."},
{0xf1, "SpeedStor"},
{0xf2, "DOS 3.3+ secondary"},
{0xf4, "SpeedStor large partition"},
{0xfe, "SpeedStor >1024 cyl. or LANstep"},
{0xff, "Xenix Bad Block Table"}
};
#endif /*__IDE_H__*/

View File

@@ -0,0 +1,16 @@
struct partition {
unsigned char boot_ind; /* 0x80 - active (unused) */
unsigned char head; /* ? */
unsigned char sector; /* ? */
unsigned char cyl; /* ? */
unsigned char sys_ind; /* ? */
unsigned char end_head; /* ? */
unsigned char end_sector; /* ? */
unsigned char end_cyl; /* ? */
unsigned int start_sect; /* starting sector counting from 0 */
unsigned int nr_sects; /* nr of sectors in partition */
};
struct disk_partition{
char name[5]; /* hda1 .. hda10...*/
struct partition part;
};

View File

@@ -0,0 +1,139 @@
#ifndef PROC_H
#define PROC_H
#include <const.h>
#include <signal.h>
#include <cnix/head.h>
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define TASK_ZOMBIE 3
#define TASK_STOPPED 4
#ifndef NULL
#define NULL ((void *)0)
#endif
#define TSS_ENTRY 5
struct i387_struct{
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long st_space[20];
};
struct tss_struct{
long linkage;
long esp0;
long ss0;
long esp1;
long ss1;
long esp2;
long ss2;
long cr3;
long eip;
long eflags;
long eax;
long ecx;
long edx;
long ebx;
long esp;
long ebp;
long esi;
long edi;
long es;
long cs;
long ss;
long ds;
long fs;
long gs;
long ldt;
unsigned short trace, bitmap;
/* Now I still have some questions about it, so not to use it. */
/* struct i387_struct i387; */
};
extern struct tss_struct tss;
typedef int (*fn_t)(void);
struct task_struct{
int need_sched;
long state;
unsigned long pg_dir;
unsigned long esp;
unsigned long eip;
struct task_struct * prev;
struct task_struct * next; /* linked in run queue */
long priority;
long counter;
unsigned long signal;
unsigned long blocked;
struct sigaction sigaction[32]; /* will be sigaction. */
int exit_code;
unsigned long end_code, end_data, start_stack;
long pid, ppid; /* pgrp, session, leader; */
int tty;
/* unsigned short uid, euid, suid;
unsigned short gid, egid, sgid;
long alarm;
long utime, stime, cutime, cstime, start_time;
unsigned short used_math;
struct desc_struct ldt[2]; */
};
union task_union{
struct task_struct task;
char stack[PAGE_SIZE];
};
extern union task_union init_task;
extern struct task_struct * current;
extern struct task_struct * run_queue;
extern struct task_struct * task[NR_TASKS];
extern void add_run(struct task_struct * tsk);
extern void del_run(struct task_struct * tsk);
/* extern void sleep_on(struct wait_queue ** p);
extern void interrupt_sleep_on(struct wait_queue ** p); */
#define ltr(n) __asm__("ltr %%ax"::"a"((unsigned long)n << 3))
#define switch_to(prev, next) do{\
__asm__ volatile("pushl %%ebx\n\t"\
"pushl %%ecx\n\t"\
"pushl %%esi\n\t"\
"pushl %%edi\n\t"\
"pushl %%ebp\n\t"\
"pushl %%fs\n\t"\
"movl %%esp, %0\n\t"\
"movl %2, %%esp\n\t"\
"movl $1f, %1\n\t"\
"pushl %3\n\t"\
"jmp __switch_to\n\t"\
"1:\n\t"\
"popl %%fs\n\t"\
"popl %%ebp\n\t"\
"popl %%edi\n\t"\
"popl %%esi\n\t"\
"popl %%ecx\n\t"\
"popl %%ebx\n\t"\
:"=m"(prev->esp), "=m"(prev->eip)\
:"m"(next->esp), "m"(next->eip), "a"(prev), "d"(next));\
}while(0)
#endif

View File

@@ -0,0 +1,12 @@
#ifndef WAIT_H
#define WAIT_H
#include <asm/system.h>
#include <cnix/sched.h>
struct wait_queue{
struct task_struct *task;
struct wait_queue *next;
};
#endif

View File

@@ -0,0 +1,9 @@
#ifndef CONST_H
#define CONST_H
#define PAGE_SIZE 4096
#define PAGE_SHIFT 12
#define NR_TASKS 64
#endif

View File

@@ -0,0 +1,45 @@
#ifndef _ERRNO_H
#define _ERRNO_H
#define ERROR 99
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define ENOTBLK 15
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define ETXTBSY 26
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
#define EDOM 33
#define ERANGE 34
#define EDEADLK 35
#define ENAMETOOLONG 36
#define ENOLCK 37
#define ENOSYS 38
#define ENOTEMPTY 39
#endif

View File

@@ -0,0 +1,59 @@
#ifndef SIGNAL_H
#define SIGNAL_H
typedef unsigned int sigset_t;
#define NSIG 16
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGUNUSED 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGUSR1 10
#define SIGSEGV 11
#define SIGUSR2 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15
#define SIGSTKFLT 16
#define SIGCHLD 17
#define SIGCONT 18
#define SIGSTOP 19
#define SIGTSTP 20
#define SIGTTIN 21
#define SIGTTOUT 22
/* sa_flags ??? */
/*
#define SA_NOCLDSTOP
#define SA_RESTART
#define SA_ONSTACK
#define SA_NOCLDWAIT
#define SA_NODEFER
#define SA_RESETHAND
#define SA_SIGINFO
*/
#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2
typedef void (*__sighandler_t)(int);
#define SIG_DFL ((__sighandler_t)0)
#define SIG_IGN ((__sighandler_t)1)
#define SIG_ERR ((__sighandler_t)-1)
struct sigaction{
__sighandler_t sa_handler;
sigset_t sa_mask;
int sa_flags;
};
#endif

View File

@@ -0,0 +1,29 @@
#ifndef _STDARG_H
#define _STDARG_H
typedef char *va_list;
/* Amount of space required in an argument list for an arg of type TYPE.
TYPE may alternatively be an expression whose type is used. */
#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
#ifndef __sparc__
#define va_start(AP, LASTARG) \
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#else
#define va_start(AP, LASTARG) \
(__builtin_saveregs (), \
AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#endif
void va_end (va_list); /* Defined in gnulib */
#define va_end(AP)
#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE))))
#endif /* _STDARG_H */

View File

@@ -0,0 +1,156 @@
#ifndef STRING_H
#define STRING_H
extern inline void memcpy(void * dest,const void * src, int n)
{
__asm__("cld\n\t"
"rep\n\t"
"movsb"
::"c" (n),"S" (src),"D" (dest)
);
}
extern inline int strlen(const char * s)
{
register int __res;
__asm__("cld\n\t"
"repne\n\t"
"scasb\n\t"
"notl %0\n\t"
"decl %0"
:"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff));
return __res;
}
extern inline
int strcmp(const char * s1, const char * s2)
{
int i, ret;
ret = 0;
for(i = 0; s1[i] != '\0' || s2[i] != '\0'; i++){
if(s1[i] != s2[i]){
ret = s1[i] > s2[i] ? 1 : -1;
break;
}
}
return ret;
}
extern inline
int strncmp(const char * cs,const char * ct,int count)
{
int i,ret;
for(i=0;i<count;i++){
if(cs[i]!=ct[i]){
ret = cs[i] > ct[i] ? 1 : -1;
return ret;
}
}
return 0;
}
extern inline
char * stpcpy(char *dest,const char *src)
{
int j;
for(j=0;src[j]!='\0';j++){
dest[j]=src[j];
}
dest[j+1] ='\0';
return dest+j;
}
extern inline
char * strcpy(char *dest,const char *src)
{
int j;
for(j=0;src[j]!='\0';j++){
dest[j]=src[j];
}
dest[j+1] ='\0';
return dest+j;
}
extern inline
char *strcat(char *dest,const char *src)
{
int i,j;
for(i=0;dest[i]!='\0';i++);
for(j=0;src[j]!='\0';j++){
dest[i]=src[j];
i++;
}
dest[i+1] ='\0';
return dest;
}
extern inline
char *strncat(char *dest,const char *src,int maxlen)
{
int i,j;
for(i=0;dest[i]!='\0';i++);
for(j=0;j<maxlen;j++){
dest[i]=src[j];
i++;
}
dest[i+1] ='\0';
return dest;
}
extern inline
char *strchr(const char *s,int c)
{
int i;
for(i=0;s[i]!='\0';i++){
if (s[i]==c)
return &s[i];
}
return '\0';
}
extern inline
char *strrchr(const char *s,int c)
{
int i,len;
len = strlen(s);
for(i=len;s[i]!='\0';i--){
if (s[i]==c)
return &s[i];
}
return '\0';
}
extern inline
char *strstr(const char *s1,const char *s2)
{
int i,j;
i =0;
for(j=0;s1[j]!='\0';j++){
if(s1[j]==s2[i]){
if(strcmp(&s1[j],s2)==0)
return &s1[j];
}
}
return '\0';
}
#endif

View File

@@ -0,0 +1,11 @@
#ifndef TTY_H
#define TTY_H
#define SIZE 64 /* the power of 2 ,so mod is replaced by head &(SIZE - 1) */
struct tty_queue {
long head;
long tail;
char buf[SIZE];
};
#endif

View File

@@ -0,0 +1,131 @@
#ifndef _UNISTD_H
#define _UNISTD_H
#ifndef NULL
#define NULL ((void *)0)
#endif
#define __NR_setup 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_chown 16
#define __NR_break 17
#define __NR_stat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_fstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_stty 31
#define __NR_gtty 32
#define __NR_access 33
#define __NR_nice 34
#define __NR_ftime 35
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_prof 44
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_phys 52
#define __NR_lock 53
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_mpx 56
#define __NR_setpgid 57
#define __NR_ulimit 58
#define __NR_uname 59
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_MP 67
#define _syscall0(type,name) \
type name(void) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name)); \
if (__res >= 0) \
return __res; \
errno = -__res; \
return -1; \
}
#define _syscall1(type,name,atype,a) \
type name(atype a) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" (a)); \
if (__res >= 0) \
return __res; \
errno = -__res; \
return -1; \
}
#define _syscall2(type,name,atype,a,btype,b) \
type name(atype a,btype b) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" (a),"c" (b)); \
if (__res >= 0) \
return __res; \
errno = -__res; \
return -1; \
}
#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
type name(atype a,btype b,ctype c) \
{ \
type __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" (a),"c" (b),"d" (c)); \
if (__res<0) \
errno=-__res , __res = -1; \
return __res;\
}
extern int errno;
int fork(void);
#endif

View File

@@ -0,0 +1,6 @@
#ifndef VGA_H
#define VGA_H
void vga_init(void);
#endif

View File

@@ -0,0 +1,17 @@
AR =ar
AS =as
LD =ld
LDFLAGS =-s -x
CC =gcc
CFLAGS =-Wall -O2 -fstrength-reduce -fomit-frame-pointer \
-finline-functions -nostdinc -I../include
OBJS = main.o
main.o: main.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,54 @@
#include <unistd.h>
#include <const.h>
#include <stdarg.h>
#include <asm/io.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <cnix/sched.h>
#include <cnix/cfile.h>
#include <string.h>
/* Do you understand why to use volatile */
extern void vga_init(void);
extern void intr_init(void);
extern void traps_init(void);
extern void timer_init(void);
extern void ide_init(void);
extern void mem_init(void);
extern void buf_init(void);
extern void fs_init(void);
extern void sched_init(void);
extern void sleep_on(struct wait_queue **p);
extern void wake_up(struct wait_queue **p);
int errno;
_syscall0(int, fork)
int main(void)
{
/* Note!!! traps_init and intr_init must be executed first. */
traps_init();
intr_init();
/* Now it's ok to enable interrupt. */
sti();
vga_init();
puts("Cnix beta version!\n");
/*for sample alloc memory,need fix!*/
cnix_malloc_init();
mem_init();
timer_init();
/* I think ide will use delay function which will be supported by
* timer, so after being laid timer_init.
*/
ide_init();
sched_init();
fs_init();
if(!fork()){
shell_init();
}
while(1);
}

View File

@@ -0,0 +1,41 @@
AS = as
LD = ld
CC = gcc
CFLAGS = -Wall -O2 -fstrength-reduce -ofomit-frame-pointer \
-finline-functions -nostdinc -I../include
OBJS = vsprintf.o printk.o i8259.o system.o syscall.o traps.o sched.o fork.o
all: kernel.o
kernel.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
vsprintf.o: vsprintf.c
$(CC) $(CFLAGS) -c $< -o $@
printk.o: printk.c
$(CC) $(CFLAGS) -c $< -o $@
i8259.o: i8259.c
$(CC) $(CFLAGS) -c $< -o $@
traps.o: traps.c
$(CC) $(CFLAGS) -c $< -o $@
system.o: system.S
$(CC) $(CFLAGS) -c $< -o $@
syscall.o: syscall.c
$(CC) $(CFLAGS) -c $< -o $@
sched.o: sched.c
$(CC) $(CFLAGS) -c $< -o $@
fork.o: fork.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o *.s
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,75 @@
#include <const.h>
#include <errno.h>
#include <asm/regs.h>
#include <cnix/sched.h>
extern struct task_struct * current;
extern struct task_struct * task[NR_TASKS];
extern void ret_from_syscall(void); /* only to get the address of it */
int find_empty_process(void)
{
int i, j;
static int next_pid = 1;
i = next_pid;
for(j = 0; j < NR_TASKS; j++, i++){
if(!task[i]){
next_pid = ((i + 1) == (NR_TASKS - 1)) ? 1 : i + 1;
return i;
}
if(i == NR_TASKS - 1)
i = 1;
}
return -EAGAIN;
}
int copy_process(int nr, struct regs_t regs)
{
unsigned long dir_pg;
struct regs_t * ptr;
struct task_struct * p;
p = (struct task_struct *)get_one_page();
if(!p)
return -EAGAIN;
*p = *current;
/* add it into run queue ??? */
p->pid = nr;
p->ppid = current->pid;
dir_pg = (unsigned long)get_one_page();
if(!dir_pg){
free_one_page(p);
return -EAGAIN;
}
p->pg_dir = dir_pg;
p->esp = (unsigned long)p + PAGE_SIZE - sizeof(struct regs_t);
/* ... */
p->eip = (unsigned long)ret_from_syscall;
/* 32 items in page dir == 128M */
if(copy_page_tables(current->pg_dir, p->pg_dir, 32) < 0){
free_page_tables(p->pg_dir, 32);
free_one_page(dir_pg);
free_one_page(p);
return -ENOMEM;
}
ptr = (struct regs_t *)(((unsigned long)p) + PAGE_SIZE -
sizeof(struct regs_t));
*ptr = regs;
ptr->eax = 0;
task[nr] = p;
add_run(p);
current->need_sched = 1;
return 0;
}

View File

@@ -0,0 +1,120 @@
#include <asm/io.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <cnix/head.h>
#define IRQ0 0x20
#define INT1_CTL 0x20
#define INT1_MASK 0x21
#define INT2_CTL 0xa0
#define INT2_MASK 0xa1
#define ENABLE_INT 0x20
#define IRQ_NUM 16
#define cli() __asm__("cli"::)
#define sti() __asm__("sti"::)
extern void hw_int0(void);
extern void hw_int1(void);
extern void hw_int2(void);
extern void hw_int3(void);
extern void hw_int4(void);
extern void hw_int5(void);
extern void hw_int6(void);
extern void hw_int7(void);
extern void hw_int8(void);
extern void hw_int9(void);
extern void hw_int10(void);
extern void hw_int11(void);
extern void hw_int12(void);
extern void hw_int13(void);
extern void hw_int14(void);
extern void hw_int15(void);
extern void printk(char * fmt, ...);
typedef void (*fn_t)(void);
static fn_t irq_table[IRQ_NUM];
static fn_t intr_gate[IRQ_NUM] = {
hw_int0, hw_int1, hw_int2, hw_int3, hw_int4, hw_int5, hw_int6, hw_int7,
hw_int8, hw_int9, hw_int10, hw_int11, hw_int12, hw_int13, hw_int14,
hw_int15
};
static void disable_irq(int irq)
{
unsigned char value;
unsigned int port;
port = irq < 8 ? INT1_MASK : INT2_MASK;
value = inb(port) | (1 << irq);
outb(value, port);
}
static void enable_irq(int irq)
{
unsigned char value;
unsigned int port;
port = irq < 8 ? INT1_MASK : INT2_MASK;
value = inb(port) & (~(1 << irq));
outb(value, port);
}
static void ack_irq(int irq)
{
outb(ENABLE_INT, INT1_CTL);
/* if will delay. */
if(irq > 8)
outb(ENABLE_INT, INT2_CTL);
}
static void default_handler(int irq)
{
printk("unexpected irq: %d\n", irq);
}
void intr_init(void)
{
int i;
for(i = 0; i < IRQ_NUM; i++)
irq_table[i] = (fn_t)default_handler;
for(i = 0; i < IRQ_NUM; i++)
set_intr_gate(IRQ0 + i, intr_gate[i]);
}
int put_irq_handler(int irq, fn_t fn)
{
if(irq < 0 || irq >= IRQ_NUM)
panic("invalid irq %d\n", irq);
if(irq_table[irq] == fn)
return 0;
if(irq_table[irq] != (fn_t)default_handler)
panic("have set one handler on irq %d\n", irq);
disable_irq(irq);
irq_table[irq] = fn;
enable_irq(irq);
return 0;
}
void do_with_irq(struct regs_t regs)
{
disable_irq(regs.index);
ack_irq(regs.index);
sti();
irq_table[regs.index]();
cli();
enable_irq(regs.index);
}

View File

@@ -0,0 +1,33 @@
#include <stdarg.h>
static char buf[1024];
int printk(const char * fmt, ...)
{
int i;
va_list args;
va_start(args, fmt);
i = vsprintf(buf, fmt, args);
va_end(args);
puts(buf);
return i;
}
int panic(const char * fmt, ...)
{
int i;
va_list args;
va_start(args, fmt);
i = vsprintf(buf, fmt, args);
va_end(args);
puts(buf);
for(;;);
return i;
}

View File

@@ -0,0 +1,231 @@
#include <const.h>
#include <asm/system.h>
#include <cnix/head.h>
#include <cnix/sched.h>
#include <cnix/wait.h>
struct{
long * a;
short b;
}stack_start = {(unsigned long)&(init_task.task) + PAGE_SIZE, 0x10};
struct tss_struct tss = {0, };
union task_union init_task;
struct task_struct * current = &(init_task.task);
/* take init_task.task as the head of run_queue */
struct task_struct * run_queue = &(init_task.task);
struct task_struct * task[NR_TASKS] = {&(init_task.task), };
static void __sleep_on(struct wait_queue **p,unsigned long flags);
void sched_init(void)
{
int i;
current->need_sched = 0;
current->state = TASK_RUNNING;
current->pg_dir = (unsigned long)kp_dir;
current->priority = 10;
current->counter = 10;
current->signal = 0;
current->blocked = 0;
for(i = 0; i < 32; i++){
current->sigaction[i].sa_handler = NULL;
current->sigaction[i].sa_mask = 0;
/* how to use it ??? */
current->sigaction[i].sa_flags = 0;
}
current->exit_code = 0;
current->pid = current->ppid = 0;
current->tty = 0;
tss.ss0 = 0x10;
tss.esp0 = (unsigned long)&(init_task.task) + PAGE_SIZE;
tss.bitmap = (unsigned long)&tss + 104;
set_tss_desc(gdt + TSS_ENTRY, &tss);
ltr(TSS_ENTRY);
run_queue->prev = run_queue->next = run_queue;
for(i = 1; i < NR_TASKS; i++)
task[i] = NULL;
}
/* add into tail */
void add_run(struct task_struct * tsk)
{
if(run_queue->next == run_queue){
run_queue->prev = run_queue->next = tsk;
tsk->prev = tsk->next = run_queue;
}else{
tsk->prev = run_queue->prev;
tsk->next = run_queue;
run_queue->prev->next = tsk;
run_queue->prev = tsk;
}
}
/* delete one task from run_queue */
void del_run(struct task_struct * tsk)
{
tsk->prev->next = tsk->next;
tsk->next->prev = tsk->prev;
tsk->prev = tsk->next = NULL;
}
void schedule(void)
{
int counter;
struct task_struct * prev, * next, * p, * sel;
current->need_sched = 0;
/* if no ok-process but idle */
if(run_queue->next == run_queue){
prev = current;
current = next = run_queue;
goto go_on;
}
repeat:
counter = 0;
p = run_queue->next;
sel = NULL;
while(p != run_queue){
if(p->counter > counter){
counter = p->counter;
sel = p;
}
p = p->next;
}
if(counter == 0){
if(current->counter == 0){
p = run_queue->next;
while(p != run_queue){
p->counter = p->priority * 10;
p = p->next;
}
}
goto repeat;
}
prev = current;
current = next = sel;
go_on:
switch_to(prev, next);
}
void __switch_to(struct task_struct * prev, struct task_struct * next) __attribute__((regparm(2)));
void __switch_to(struct task_struct * prev, struct task_struct * next)
{
tss.esp0 = (unsigned long)next + PAGE_SIZE;
__asm__("movl %%eax, %%cr3"::"a"((unsigned long)next->pg_dir));
}
void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
{
unsigned long flags;
save_flags(flags);
cli();
if(!*p){
wait->next = wait;
*p = wait;
}else{
wait->next = (*p)->next;
(*p)->next = wait;
}
restore_flags(flags);
}
/* remove wait from wait_queue whose head is *p */
void remove_wait_queue(struct wait_queue ** p , struct wait_queue *wait)
{
unsigned long flags;
struct wait_queue * tmp;
save_flags(flags);
cli();
if((*p == wait) && ((*p = wait->next) == wait)){
*p = NULL;
}else{
tmp = wait;
while(tmp->next != wait)
tmp = tmp->next;
tmp->next = wait->next;
}
wait->next = NULL;
restore_flags(flags);
}
void sleep_on(struct wait_queue ** p)
{
__sleep_on(p, TASK_UNINTERRUPTIBLE);
}
void interrupt_sleep_on(struct wait_queue ** p)
{
__sleep_on(p, TASK_INTERRUPTIBLE);
}
static void __sleep_on(struct wait_queue ** p, unsigned long state)
{
unsigned long flags;
struct wait_queue wait = {current, NULL};
if (!p)
return;
if (current->pid == 0)
panic("Task 0 want to sleep, giving up ....\n");
del_run(current);
current->state = state;
add_wait_queue(p, &wait);
save_flags(flags);
sti();
schedule();
remove_wait_queue(p, &wait);
restore_flags(flags);
}
void wakeup(struct wait_queue ** p)
{
struct wait_queue * tmp;
struct task_struct * tsk;
if(!p || !(tmp = *p))
return ;
do{
tsk = tmp->task;
if(tsk->state == TASK_UNINTERRUPTIBLE
|| tsk->state == TASK_INTERRUPTIBLE){
tsk -> state = TASK_RUNNING;
add_run(tsk);
}
tmp = tmp->next;
}while(tmp != *p);
current->need_sched = 1;
}

View File

@@ -0,0 +1,32 @@
#include <errno.h>
#include <stdarg.h>
#include <asm/regs.h>
static char buf[1024];
int sys_fork(struct regs_t regs)
{
int i, ret;
i = find_empty_process();
if(i < 0)
return i;
ret = copy_process(i, regs);
if(ret < 0)
return ret;
return i;
}
int sys_printf(const char * string)
{
puts(string);
return 0;
}
void sys_null_call(void)
{
printk("calling sys_null_call...\n");
}

View File

@@ -0,0 +1,351 @@
/* #include <errno.h> */
need_sched = 0
nr_syscall = 256
ENOSYS = 38
EFLAGS = 48
CS = 44
EIP = 40
INDEX = 36
ES = 32
DS = 28
EAX = 24
EBP = 20
EDI = 16
ESI = 12
EDX = 8
ECX = 4
EBX = 0
#define SAVE_SPOT \
cld; \
pushl %es; \
pushl %ds; \
pushl %eax; \
pushl %ebp; \
pushl %edi; \
pushl %esi; \
pushl %edx; \
pushl %ecx; \
pushl %ebx; \
movl $0x10, %edx; \
movl %edx, %ds; \
movl %edx, %es; \
#define RESTORE_SPOT \
popl %ebx; \
popl %ecx; \
popl %edx; \
popl %esi; \
popl %edi; \
popl %ebp; \
popl %eax; \
popl %ds; \
popl %es; \
.global system_call
.global hw_int0, hw_int1, hw_int2, hw_int3, hw_int4, hw_int5, hw_int6, hw_int7
.global hw_int8, hw_int9, hw_int10, hw_int11, hw_int12, hw_int13, hw_int14,
.global hw_int15
.global divide_err, debug, nmi, int3, overflow, bounds, invalid_op
.global device_not_avl, double_fault, coprocessor_segment_overrun, invalid_tss
.global segment_not_present, stack_segment, general_protection, page_fault
.global coprocessor_fault
.global ret_from_syscall
.align 2
bad_syscall:
movl $-ENOSYS, EAX(%esp)
jmp ret_from_syscall
.align 2
system_call:
pushl %eax
SAVE_SPOT
cmpl $nr_syscall - 1, %eax
ja bad_syscall
call *syscall_table(, %eax, 4)
movl %eax, EAX(%esp)
ret_from_syscall:
/* But I think not necessary to check, because ret_from_syscall, must return
* to user state. :-) But when call from kernel, ...
*/
/* movl CS(%esp), %eax
testl $0x03, %eax
je restore_all
*/
ret_with_reschedule:
movl current, %ebx
cmpl $0, need_sched(%ebx)
jne reschedule
/* do something to check signal, if have, then jmp do_with_signal */
restore_all:
RESTORE_SPOT
addl $4, %esp
iret
reschedule:
call schedule
/* why not ret_from_intr, the same to ret_from_syscall */
jmp ret_from_syscall
ret_from_intr:
/* assume nested interrupt will not happen */
/* movl CS(%esp), %eax
testl $0x03, %eax */
jne ret_with_reschedule
jmp restore_all
.align 2
hw_int0:
pushl $0
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int1:
pushl $1
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int2:
pushl $2
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int3:
pushl $3
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int4:
pushl $4
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int5:
pushl $5
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int6:
pushl $6
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int7:
pushl $7
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int8:
pushl $8
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int9:
pushl $9
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int10:
pushl $10
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int11:
pushl $11
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int12:
pushl $12
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int13:
pushl $13
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int14:
pushl $14
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
hw_int15:
pushl $15
SAVE_SPOT
call do_with_irq
jmp ret_from_intr
.align 2
divide_err:
pushl $0
pushl $0
jmp execption
.align 2
debug:
pushl $0
pushl $1
jmp execption
.align 2
nmi:
pushl $0
pushl $2
jmp execption
.align 2
int3:
pushl $0
pushl $3
jmp execption
.align 2
overflow:
pushl $0
pushl $4
jmp execption
.align 2
bounds:
pushl $0
pushl $5
jmp execption
.align 2
invalid_op:
pushl $0
pushl $6
jmp execption
.align 2
device_not_avl:
pushl $0
pushl $7
jmp execption
.align 2
double_fault:
pushl $8
jmp execption
.align 2
coprocessor_segment_overrun:
pushl $0
pushl $9
jmp execption
.align 2
invalid_tss:
pushl $10
jmp execption
.align 2
segment_not_present:
pushl $11
jmp execption
.align 2
stack_segment:
pushl $12
jmp execption
.align 2
general_protection:
pushl $13
jmp execption
.align 2
page_fault:
pushl $14
jmp execption
.align 2
coprocessor_fault:
pushl $0
pushl $15
jmp execption
execption:
cld
pushl %ds
pushl %eax
pushl %ebp
pushl %edi
pushl %esi
pushl %edx
pushl %ecx
pushl %ebx
movl $0x10, %eax
movl %eax, %ds
call do_with_execption
popl %ebx
popl %ecx
popl %edx
popl %esi
popl %edi
popl %ebp
popl %eax
popl %ds
addl $8, %esp
iret
.data
.global syscall_table
syscall_table:
.long sys_null_call
.long sys_null_call
.long sys_fork
.rept 64
.long sys_null_call
.endr
.long sys_printf
.rept nr_syscall - 68
.long sys_null_call
.endr

View File

@@ -0,0 +1,65 @@
#include <asm/regs.h>
#include <asm/system.h>
#include <cnix/head.h>
extern void divide_err(void);
extern void debug(void);
extern void nmi(void);
extern void int3(void);
extern void overflow(void);
extern void bounds(void);
extern void invalid_op(void);
extern void device_not_avl(void);
extern void double_fault(void);
extern void coprocessor_segment_overrun(void);
extern void invalid_tss(void);
extern void segment_not_present(void);
extern void stack_segment(void);
extern void general_protection(void);
extern void page_fault(void);
extern void coprocessor_fault(void);
extern void system_call(void);
static void reserved(void)
{
panic("error: idt is reserved.\n");
}
void traps_init(void)
{
int index;
set_trap_gate(0, divide_err);
set_trap_gate(1, debug);
set_trap_gate(2, nmi);
/* ...... */
set_trap_gate(3, int3);
set_trap_gate(4, overflow);
set_trap_gate(5, bounds);
set_trap_gate(6, invalid_op);
set_trap_gate(7, device_not_avl);
set_trap_gate(8, double_fault);
set_trap_gate(9, coprocessor_segment_overrun);
set_trap_gate(10, invalid_tss);
set_trap_gate(11, segment_not_present);
set_trap_gate(12, stack_segment);
set_trap_gate(13, general_protection);
set_trap_gate(14, page_fault);
set_trap_gate(15, coprocessor_fault);
for(index = 16; index < 32; index++)
set_trap_gate(index, reserved);
/* when call, does it auto-cli */
set_system_gate(0x80, &system_call);
}
void do_with_execption(struct regs_t regs)
{
if(regs.es == 14)
panic("page_fault\n");
panic("execption %d err_code %x cs: %x eip: %x\n", regs.es, regs.index,
regs.cs, regs.eip);
}

View File

@@ -0,0 +1,227 @@
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
#include <stdarg.h>
#include <string.h>
/* we use this so that we can do without the ctype library */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
static int skip_atoi(const char **s)
{
int i=0;
while (is_digit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */
#define do_div(n,base) ({ \
int __res; \
__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \
__res; })
static char * number(char * str, int num, int base, int size, int precision
,int type)
{
char c,sign,tmp[36];
const char *digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i;
if (type&SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz";
if (type&LEFT) type &= ~ZEROPAD;
if (base<2 || base>36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ' ;
if (type&SIGN && num<0) {
sign='-';
num = -num;
} else
sign=(type&PLUS) ? '+' : ((type&SPACE) ? ' ' : 0);
if (sign) size--;
if (type&SPECIAL)
if (base==16) size -= 2;
else if (base==8) size--;
i=0;
if (num==0)
tmp[i++]='0';
else while (num!=0)
tmp[i++]=digits[do_div(num,base)];
if (i>precision) precision=i;
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
*str++ = ' ';
if (sign)
*str++ = sign;
if (type&SPECIAL)
if (base==8)
*str++ = '0';
else if (base==16) {
*str++ = '0';
*str++ = digits[33];
}
if (!(type&LEFT))
while(size-->0)
*str++ = c;
while(i<precision--)
*str++ = '0';
while(i-->0)
*str++ = tmp[i];
while(size-->0)
*str++ = ' ';
return str;
}
int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
int i;
char * str;
char *s;
int *ip;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
for (str=buf ; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if (is_digit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if (is_digit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
qualifier = *fmt;
++fmt;
}
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
*str++ = ' ';
*str++ = (unsigned char) va_arg(args, int);
while (--field_width > 0)
*str++ = ' ';
break;
case 's':
s = va_arg(args, char *);
len = strlen(s);
if (precision < 0)
precision = len;
else if (len > precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
*str++ = ' ';
for (i = 0; i < len; ++i)
*str++ = *s++;
while (len < field_width--)
*str++ = ' ';
break;
case 'o':
str = number(str, va_arg(args, unsigned long), 8,
field_width, precision, flags);
break;
case 'p':
if (field_width == -1) {
field_width = 8;
flags |= ZEROPAD;
}
str = number(str,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
break;
case 'x':
flags |= SMALL;
case 'X':
str = number(str, va_arg(args, unsigned long), 16,
field_width, precision, flags);
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
str = number(str, va_arg(args, unsigned long), 10,
field_width, precision, flags);
break;
case 'n':
ip = va_arg(args, int *);
*ip = (str - buf);
break;
default:
if (*fmt != '%')
*str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
break;
}
}
*str = '\0';
return str-buf;
}

View File

@@ -0,0 +1,21 @@
AR = ar
AS = as
LD = ld
CC = gcc
CFLAGS = -Wall -O2 -fstrength-reduce -ofomit-frame-pointer \
-finline-functions -nostdinc -I../include
OBJS = write.o
all: lib.a
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
write.o: write.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o *.a
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,247 @@
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
/* we use this so that we can do without the ctype library */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
static int skip_atoi(const char **s)
{
int i=0;
while (is_digit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */
#define do_div(n,base) ({ \
int __res; \
__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \
__res; })
static char * number(char * str, int num, int base, int size, int precision
,int type)
{
char c,sign,tmp[36];
const char *digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i;
if (type&SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz";
if (type&LEFT) type &= ~ZEROPAD;
if (base<2 || base>36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ' ;
if (type&SIGN && num<0) {
sign='-';
num = -num;
} else
sign=(type&PLUS) ? '+' : ((type&SPACE) ? ' ' : 0);
if (sign) size--;
if (type&SPECIAL)
if (base==16) size -= 2;
else if (base==8) size--;
i=0;
if (num==0)
tmp[i++]='0';
else while (num!=0)
tmp[i++]=digits[do_div(num,base)];
if (i>precision) precision=i;
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
*str++ = ' ';
if (sign)
*str++ = sign;
if (type&SPECIAL)
if (base==8)
*str++ = '0';
else if (base==16) {
*str++ = '0';
*str++ = digits[33];
}
if (!(type&LEFT))
while(size-->0)
*str++ = c;
while(i<precision--)
*str++ = '0';
while(i-->0)
*str++ = tmp[i];
while(size-->0)
*str++ = ' ';
return str;
}
static int vsprintf(char *buf, const char *fmt, va_list args)
{
int len;
int i;
char * str;
char *s;
int *ip;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
for (str=buf ; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if (is_digit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if (is_digit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
qualifier = *fmt;
++fmt;
}
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
*str++ = ' ';
*str++ = (unsigned char) va_arg(args, int);
while (--field_width > 0)
*str++ = ' ';
break;
case 's':
s = va_arg(args, char *);
len = strlen(s);
if (precision < 0)
precision = len;
else if (len > precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
*str++ = ' ';
for (i = 0; i < len; ++i)
*str++ = *s++;
while (len < field_width--)
*str++ = ' ';
break;
case 'o':
str = number(str, va_arg(args, unsigned long), 8,
field_width, precision, flags);
break;
case 'p':
if (field_width == -1) {
field_width = 8;
flags |= ZEROPAD;
}
str = number(str,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
break;
case 'x':
flags |= SMALL;
case 'X':
str = number(str, va_arg(args, unsigned long), 16,
field_width, precision, flags);
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
str = number(str, va_arg(args, unsigned long), 10,
field_width, precision, flags);
break;
case 'n':
ip = va_arg(args, int *);
*ip = (str - buf);
break;
default:
if (*fmt != '%')
*str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
break;
}
}
*str = '\0';
return str-buf;
}
static char buf[1024];
int MP(const char * fmt, ...)
{
int i;
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
__asm__("int $0x80"
:"=a"(i)
:"0"(__NR_MP), "b"(buf)
);
return i;
}

View File

@@ -0,0 +1,21 @@
LD = ld
CC = gcc
CFLAGS = -Wall -O2 -fstrength-reduce -ofomit-frame-pointer \
-finline-functions -nostdinc -I../include
OBJS = memory.o malloc.o
all: mm.o
mm.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
%.o%.c:
$(CC) $(CFLAGS) -c -o $@ $<
memory.o: memory.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.o
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,26 @@
#include <cnix/config.h>
/*cnix malloc memery form 2M to 4M*/
static char * start_mem ;
static char * end_mem ;
static char * current_mem;
static char * next_mem;
char *
cnix_malloc(int size)
{
current_mem = next_mem;
if( current_mem + size >end_mem )
return -1;
next_mem = current_mem +size;
return current_mem;
}
cnix_malloc_init()
{
start_mem = 0x3E00000;
end_mem = start_mem+0x200000;
next_mem = start_mem;
}

View File

@@ -0,0 +1,263 @@
#include <const.h>
#include <asm/system.h>
#include <cnix/head.h>
#include <cnix/config.h>
#define KP_DIR_SIZE (HIGH_MEM / (PAGE_SIZE * 1024))
#define TOTAL_PAGES ((HIGH_MEM - LOW_MEM) / PAGE_SIZE)
#define invalidate() \
__asm__("movl %%eax, %%cr3"::"a"((unsigned long)kp_dir))
unsigned long low_page_mem = (unsigned long)&end;
struct page{
int count;
/* This could be also get from the address of page struct */
unsigned long addr;
struct page * prev;
struct page * next;
};
/* from LOW_MEM to ... HIGH_MEM */
struct page mem_map[TOTAL_PAGES + 1];
struct page * free_pg = &mem_map[TOTAL_PAGES];
/* as head, count will be used to count free
* pages, the last one in this queue's next points it.
* When operating on it, do we need to cli ?
*/
void init_list(void)
{
free_pg->count = 0;
free_pg->addr = 0;
free_pg->prev = (struct page *)free_pg;
free_pg->next = (struct page *)free_pg;
}
/* add pg to tail */
int add_list(struct page * pg)
{
/* need to lock ??? */
free_pg->count++;
if(free_pg->count == 0){
free_pg->prev = free_pg->next = pg;
pg->prev = pg->next = free_pg;
}else{
pg->next = free_pg;
pg->prev = free_pg->prev;
free_pg->prev->next = pg;
free_pg->prev = pg;
}
return 0;
}
/* get pg from head */
struct page * del_list(void)
{
struct page * pg;
if(free_pg->count == 0)
return (struct pg *)0;
/* need to lock */
free_pg->count--;
pg = free_pg->next;
free_pg->next = pg->next;
pg->next->prev = free_pg;
pg->prev = pg->next = (struct page *)0;
return (struct page *)pg;
}
void mem_init(void)
{
int i, j, index;
long * kpd_ptr, * kp_ptr;
unsigned long from_8M;
kpd_ptr = (unsigned long *)kp_dir;
low_page_mem = (low_page_mem + (PAGE_SIZE - 1)) & (~(PAGE_SIZE - 1));
kp_ptr = (long *)low_page_mem;
from_8M = 0x800000;
/* setup paging for 8M - HIGH_MEM */
for(i = 0; i < KP_DIR_SIZE; kpd_ptr++, i++){
/* item 0 and item 1 have been initialized in head.S */
if(i > 1){
*kpd_ptr = (unsigned long)kp_ptr | 7;
for(j = 0; j < (PAGE_SIZE / 4); kp_ptr++, j++){
*kp_ptr = from_8M | 7;
from_8M += PAGE_SIZE;
}
}
}
invalidate();
/* from low_page_mem cound be given out */
low_page_mem += PAGE_SIZE * (KP_DIR_SIZE - 2);
/* reserve memory under low_page_mem */
for(index = 0; index < (low_page_mem -LOW_MEM) / PAGE_SIZE; index++){
/* I think this count will not be used. */
mem_map[index].count = 1;
mem_map[index].addr = LOW_MEM + (i * PAGE_SIZE);
mem_map[index].prev = (struct page *)0;
mem_map[index].next = (struct page *)0;
}
init_list();
for(; index < TOTAL_PAGES; index++){
mem_map[index].count = 0;
mem_map[index].addr = LOW_MEM + (index * PAGE_SIZE);
add_list(&mem_map[index]);
}
}
unsigned long get_one_page(void)
{
unsigned long * addr;
struct page * pg;
pg = del_list();
if(pg){
/* clear the page */
addr = (unsigned long *)pg->addr;
do{
*addr = 0;
addr++;
}while(((unsigned long)addr - pg->addr) < PAGE_SIZE);
return pg->addr;
}
return 0;
}
void free_one_page(unsigned long addr)
{
if(addr & 0xfff)
panic("in free_one_page, address not alignment\n");
/* I think kernel pages will not be freed */
if(addr < low_page_mem)
return;
/* can't be this large */
if(addr >= HIGH_MEM)
return;
addr = (addr - LOW_MEM) >> 12;
/* need to lock ??? */
mem_map[addr].count--;
if(mem_map[addr].count)
return;
add_list(&mem_map[addr]);
}
/* I think when one process to do exit, it must release all pages it takes,
and then it's page dir, then it's pcb. */
/* from is page dir, and size is how many items in page dir. what's in %cr3 now
* I think, it's kp_dir.
*/
int free_page_tables(unsigned long from, int size)
{
unsigned long * pg_table, *pg_dir, nr;
if(from & 0xfff)
panic("in free_page_tables, error not alignment\n");
if(from == kp_dir)
panic("in free_page_tables, trying to free kernel page dir\n");
pg_dir = (unsigned long *)from;
for(; size-- > 0; pg_dir++){
if(!(*pg_dir & 1))
continue;
/* if it's kernel page dir item */
if((((unsigned long)pg_dir & (PAGE_SIZE - 1)) / 4)
< KP_DIR_SIZE){
*pg_dir = 0;
continue;
}
nr = 1024;
pg_table = (unsigned long *)*pg_dir;
for(; nr-- > 0; pg_table++){
if(*pg_table & 1)
free_one_page(*pg_table & 0xfffff000);
*pg_table = 0;
}
/* sometimes I think it's not necessary to & ... */
free_one_page(*pg_dir & 0xfffff000);
*pg_dir = 0;
}
return 0;
}
int copy_page_tables(unsigned long from, unsigned long to, int size)
{
int nr;
unsigned long * from_dir, * to_dir;
unsigned long * from_pg_table, * to_pg_table, this_pg;
if(from & 0xfff || to & 0xfff)
panic("in copy_page_tables, address not alignment\n");
from_dir = (unsigned long *)from;
to_dir = (unsigned long *)to;
for(; size-- > 0; from_dir++, to_dir++){
if(*to_dir)
panic("in copy_page_tables, \
page dir item already exist\n");
if(!(*from_dir & 1))
continue;
/* if it's kernel page dir item, skip next ... */
if((((unsigned long)from_dir & (PAGE_SIZE - 1)) / 4)
< KP_DIR_SIZE){
*to_dir = *from_dir;
continue;
}
from_pg_table = (unsigned long *)(*from_dir & 0xfffff000);
if(!(to_pg_table = (unsigned long *)get_one_page()))
return -1;
*to_dir = (unsigned long)to_pg_table | 7;
nr = 1024;
for(; nr-- > 0; from_pg_table++, to_pg_table++){
this_pg = *from_pg_table;
if(!(this_pg & 1))
continue;
/* could not be given out, I think this condition
* doesn't exist.
*/
if(this_pg < low_page_mem)
panic("in copy_page_tables, can't happen.");
/* copy on write, now write page_fault. */
this_pg &= ~2;
*from_pg_table = this_pg;
*to_pg_table = this_pg;
this_pg = (this_pg - LOW_MEM) >> 12;
/* need to lock ???, will be decrement in ??? */
mem_map[this_pg].count++;
}
}
return 0;
}

View File

@@ -0,0 +1,20 @@
LD = ld
CC = gcc
CFLAGS = -Wall -O2 -fstrength-reduce -ofomit-frame-pointer \
-finline-functions -nostdinc -I../include
OBJS = command.o
all: shell.o
shell.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
%.o%.c:
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.o
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,129 @@
#include <unistd.h>
#include <const.h>
#include <stdarg.h>
#include <asm/io.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <cnix/sched.h>
#include <cnix/cfile.h>
#include <string.h>
int volatile count = 0;
int volatile flag = 0;
long volatile timer_count = 0;
int volatile sflag = 0;
extern void reboot(void);
shell_init()
{
init();
}
static void init()
{
int i;
unsigned char c;
unsigned char buff[20];
/* PAGE_SIZE is the size of the stack of user stack */
/* _syscall2(int, exec, fn_t, func, int, size) */
/* exec(shell, PAGE_SIZE); */
for(;;){
printk("\n[cnix@ 51.net]# ");
i = 0;
c = getchar();
while(c != '\n' && i < 20){
printk("%c", c);
buff[i++] = c;
c = getchar();
while (c ==127){
delchar();
buff[i]='\0';
i--;
c = getchar();
}
}
buff[i] = '\0';
printk("\n");
if(c == '\n'){
if(!strcmp(buff, "help"))
help();
if(!strcmp(buff, "malloc"))
test_malloc();
if(!strcmp(buff, "partition"))
print_part_list();
if(!strcmp(buff, "readme"))
read_file("readme");
if(!strcmp(buff, "shell"))
exe_shell("readme");
if(!strcmp(buff, "abc"))
read_file("abc");
if(!strcmp(buff, "cnix"))
printk("Welcome!");
else if(!strcmp(buff, "reboot"))
reboot();
continue;
}
printk("%s", buff);
}
}
/*for test ,and delete it some days later*/
test_malloc()
{
char *abc;
char *s1 = "12345";
abc = cnix_malloc(0x10);
strcpy(abc,s1);
printk("\naddress:%x,%s\n",abc,abc);
}
read_file(char *filename)
{
struct cfile *file_test;
file_test = cnix_open("cnix",filename);
printk("\n%s\n",file_test->file_buf);
}
static char *exe_entry;
exe_shell(char *filename)
{
struct cfile *file_test;
int i;
file_test = cnix_open("cnix",filename);
for(i=0x1000;i<0x100f;i++)
printk("%x ",file_test->file_buf[i]);
printk("\n");
exe_entry = &file_test->file_buf[0x1000];
__asm__("push %%eax\n\t"
"call *%%eax\n\t"
"popl %%eax\n\t"
:::"ax");
}
help()
{
printk("\n");
printk("partition shell readme cnix help\n");
}

View File

@@ -0,0 +1,15 @@
CC = gcc
CFLAGS = -g
all: build makeimg
build: build.c
$(CC) $(CFLAGS) -o build build.c
makeimg: makeimg.c
$(CC) $(CFLAGS) -o makeimg makeimg.c
clean:
rm -f *.o build makeimg
rm -f *~
rm -f .*.swp

View File

@@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#define MINIX_HEADER 32
#define GCC_HEADER 1024
void die(char * str)
{
fprintf(stderr,"%s\n",str);
exit(1);
}
void usage(void)
{
die("Usage: build boot system [> image]");
}
int main(int argc, char ** argv)
{
int i, c, id;
char buf[512];
if(argc != 3)
usage();
for(i = 0;i < sizeof buf; i++)
buf[i] = 0;
if((id = open(argv[1], O_RDONLY, 0)) < 0)
die("Unable to open 'boot'");
i = read(id, buf, sizeof buf);
fprintf(stderr,"Boot sector %d bytes.\n",i);
i = write(1,buf,512);
if(i!=512)
die("Write call failed");
close (id);
if ((id = open(argv[2], O_RDONLY, 0)) < 0)
die("Unable to open 'system'");
for (i = 0; (c = read(id, buf, sizeof buf)) > 0 ; i += c )
if (write(1, buf, c) != c)
die("Write call failed");
close(id);
fprintf(stderr,"System %d bytes.\n",i);
return(0);
}

View File

@@ -0,0 +1,72 @@
/* This tool is used to make a.img */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FD0_SIZE 1474560 /* 1.44M */
#define BUFSIZE 512
int main(int argc, char **argv)
{
int fd_in, fd_out;
int n;
int size = 0;
char buf[BUFSIZE];
if (argc != 3) {
printf("Usage:\t%s infile outfile\n",
argv[0]);
exit(-1);
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in == -1) {
printf("Can't open %s\n", argv[1]);
exit(-1);
}
fd_out = open(argv[2], O_WRONLY | O_CREAT, 0600);
if (fd_out == -1) {
printf("Can't open %s\n", argv[2]);
close(fd_in);
exit(-1);
}
// printf("Begin to read %s...\n", argv[1]);
while (1) {
n = read(fd_in, buf, BUFSIZE);
if (n == 0 || n == -1)
break;
size += n;
if (write(fd_out, buf, n) != n) {
printf("write error.\n");
close(fd_in);
close(fd_out);
exit(-1);
}
}
// printf("read %s done\n", argv[1]);
if (size > FD0_SIZE) {
printf("em..%s is bigger than 1.4M.\n", argv[2]);
close(fd_in);
close(fd_out);
exit(-1);
}
// printf("Begin to lseek...\n");
n = FD0_SIZE - size - 2;
n = lseek(fd_out, n, SEEK_CUR);
if (n == -1)
printf("Lseek error\n");
// printf("lseek done: %d\n", n);
write(fd_out, "dd", 2);
close(fd_in);
close(fd_out);
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

41959
distributions/cnix/linuxmm.pdf Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.