5051da6de3
fix race in mknod / creat use last component in dirent in mknod, not path
155 lines
5 KiB
Text
155 lines
5 KiB
Text
bochs 2.2.6:
|
|
./configure --enable-smp --enable-disasm --enable-debugger --enable-all-optimizations --enable-4meg-pages --enable-global-pages --enable-pae --disable-reset-on-triple-fault
|
|
bochs CVS after 2.2.6:
|
|
./configure --enable-smp --enable-disasm --enable-debugger --enable-all-optimizations --enable-4meg-pages --enable-global-pages --enable-pae
|
|
|
|
bootmain.c doesn't work right if the ELF sections aren't
|
|
sector-aligned. so you can't use ld -N. and the sections may also need
|
|
to be non-zero length, only really matters for tiny "kernels".
|
|
|
|
kernel loaded at 1 megabyte. stack same place that bootasm.S left it.
|
|
|
|
kinit() should find real mem size
|
|
and rescue useable memory below 1 meg
|
|
|
|
no paging, no use of page table hardware, just segments
|
|
|
|
no user area: no magic kernel stack mapping
|
|
so no copying of kernel stack during fork
|
|
though there is a kernel stack page for each process
|
|
|
|
no kernel malloc(), just kalloc() for user core
|
|
|
|
user pointers aren't valid in the kernel
|
|
|
|
are interrupts turned on in the kernel? yes.
|
|
|
|
pass curproc explicitly, or implicit from cpu #?
|
|
e.g. argument to newproc()?
|
|
hmm, you need a global curproc[cpu] for trap() &c
|
|
|
|
no stack expansion
|
|
|
|
test running out of memory, process slots
|
|
|
|
we can't really use a separate stack segment, since stack addresses
|
|
need to work correctly as ordinary pointers. the same may be true of
|
|
data vs text. how can we have a gap between data and stack, so that
|
|
both can grow, without committing 4GB of physical memory? does this
|
|
mean we need paging?
|
|
|
|
perhaps have fixed-size stack, put it in the data segment?
|
|
|
|
oops, if kernel stack is in contiguous user phys mem, then moving
|
|
users' memory (e.g. to expand it) will wreck any pointers into the
|
|
kernel stack.
|
|
|
|
do we need to set fs and gs? so user processes can't abuse them?
|
|
|
|
setupsegs() may modify current segment table, is that legal?
|
|
|
|
trap() ought to lgdt on return, since currently only done in swtch()
|
|
|
|
protect hardware interrupt vectors from user INT instructions?
|
|
|
|
test out-of-fd cases for creating pipe.
|
|
test pipe reader closes then write
|
|
test two readers, two writers.
|
|
test children being inherited by grandparent &c
|
|
|
|
some sleep()s should be interruptible by kill()
|
|
|
|
locks
|
|
init_lock
|
|
sequences CPU startup
|
|
proc_table_lock
|
|
also protects next_pid
|
|
per-fd lock *just* protects count read-modify-write
|
|
also maybe freeness?
|
|
memory allocator
|
|
printf
|
|
|
|
in general, the table locks protect both free-ness and
|
|
public variables of table elements
|
|
in many cases you can use table elements w/o a lock
|
|
e.g. if you are the process, or you are using an fd
|
|
|
|
lock order
|
|
per-pipe lock
|
|
proc_table_lock fd_table_lock kalloc_lock
|
|
console_lock
|
|
|
|
do you have to be holding the mutex in order to call wakeup()? yes
|
|
|
|
device interrupts don't clear FL_IF
|
|
so a recursive timer interrupt is possible
|
|
|
|
what does inode->busy mean?
|
|
might be held across disk reads
|
|
no-one is allowed to do anything to the inode
|
|
protected by inode_table_lock
|
|
inode->count counts in-memory pointers to the struct
|
|
prevents inode[] element from being re-used
|
|
protected by inode_table_lock
|
|
|
|
blocks and inodes have ad-hoc sleep-locks
|
|
provide a single mechanism?
|
|
|
|
test 14-character file names
|
|
and file arguments longer than 14
|
|
|
|
kalloc() can return 0; do callers handle this right?
|
|
|
|
OH! recursive interrupts will use up any amount of cpu[].stack!
|
|
underflow and wrecks *previous* cpu's struct
|
|
|
|
disk scheduling
|
|
mkdir
|
|
sh arguments
|
|
sh redirection
|
|
indirect blocks
|
|
is there a create/create race for same file name?
|
|
resulting in two entries w/ same name in directory?
|
|
why does shell often ignore first line of input?
|
|
|
|
test: one process unlinks a file while another links to it
|
|
test: one process opens a file while another deletes it
|
|
test: mkdir. deadlock d/.. vs ../d
|
|
test: sub-sub directories. mkdir("d1/d2")
|
|
test: dup() shared fd->off
|
|
test: indirect blocks. files and directories.
|
|
test: sbrk
|
|
test: does echo foo > x truncate x?
|
|
test: does create/mkdir/link extract last component correctly?
|
|
does namei insist that all the intermediate directories exist?
|
|
test: creat/link/mkdir w/ / in name
|
|
test: try to create dir ents when intermediate dir doesn't exist
|
|
or is a file, not a dir
|
|
|
|
make proc[0] runnable
|
|
cpu early tss and gdt
|
|
how do we get cpu0 scheduler() to use mpstack, not proc[0].kstack?
|
|
when iget() first sleeps, where does it longjmp to?
|
|
maybe set up proc[0] to be runnable, with entry proc0main(), then
|
|
have main() call scheduler()?
|
|
perhaps so proc[0] uses right kstack?
|
|
and scheduler() uses mpstack?
|
|
ltr sets the busy bit in the TSS, faults if already set
|
|
so gdt and TSS per cpu?
|
|
we don't want to be using some random process's gdt when it changes it.
|
|
maybe get rid of per-proc gdt and ts
|
|
one per cpu
|
|
refresh it when needed
|
|
setupsegs(proc *)
|
|
|
|
why do we get 0 characters from keyboard?
|
|
are the locks in the right place in keyboardintr?
|
|
|
|
sh: support pipes? leave it for the class?
|
|
sh: dynamic memory allocation?
|
|
sh: should sh support ; () & --- need malloc
|
|
sh: stop stdin on ctrl-d (for cat > y)
|
|
|
|
really should have bdwrite() for file content
|
|
and make some inode updates async
|
|
so soft updates make sense
|