init creates console, opens 0/1/2, runs sh
sh accepts 0-argument commands (like userfs) reads from console
This commit is contained in:
parent
5be0039ce9
commit
17a856577f
11 changed files with 164 additions and 40 deletions
18
Makefile
18
Makefile
|
@ -46,12 +46,12 @@ bootblock : bootasm.S bootmain.c
|
||||||
$(OBJCOPY) -S -O binary bootblock.o bootblock
|
$(OBJCOPY) -S -O binary bootblock.o bootblock
|
||||||
./sign.pl bootblock
|
./sign.pl bootblock
|
||||||
|
|
||||||
kernel : $(OBJS) bootother.S user1 usertests userfs
|
kernel : $(OBJS) bootother.S userfs init
|
||||||
$(CC) -nostdinc -I. -c bootother.S
|
$(CC) -nostdinc -I. -c bootother.S
|
||||||
$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
|
$(LD) -N -e start -Ttext 0x7000 -o bootother.out bootother.o
|
||||||
$(OBJCOPY) -S -O binary bootother.out bootother
|
$(OBJCOPY) -S -O binary bootother.out bootother
|
||||||
$(OBJDUMP) -S bootother.o > bootother.asm
|
$(OBJDUMP) -S bootother.o > bootother.asm
|
||||||
$(LD) -Ttext 0x100000 -e main0 -o kernel $(OBJS) -b binary bootother user1 usertests userfs
|
$(LD) -Ttext 0x100000 -e main0 -o kernel $(OBJS) -b binary bootother userfs init
|
||||||
$(OBJDUMP) -S kernel > kernel.asm
|
$(OBJDUMP) -S kernel > kernel.asm
|
||||||
|
|
||||||
vectors.S : vectors.pl
|
vectors.S : vectors.pl
|
||||||
|
@ -79,15 +79,23 @@ userfs : userfs.o $(ULIB)
|
||||||
$(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB)
|
$(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB)
|
||||||
$(OBJDUMP) -S userfs > userfs.asm
|
$(OBJDUMP) -S userfs > userfs.asm
|
||||||
|
|
||||||
|
init : init.o $(ULIB)
|
||||||
|
$(LD) -N -e main -Ttext 0 -o init init.o $(ULIB)
|
||||||
|
$(OBJDUMP) -S init > init.asm
|
||||||
|
|
||||||
|
sh : sh.o $(ULIB)
|
||||||
|
$(LD) -N -e main -Ttext 0 -o sh sh.o $(ULIB)
|
||||||
|
$(OBJDUMP) -S sh > sh.asm
|
||||||
|
|
||||||
mkfs : mkfs.c fs.h
|
mkfs : mkfs.c fs.h
|
||||||
cc -o mkfs mkfs.c
|
cc -o mkfs mkfs.c
|
||||||
|
|
||||||
fs.img : mkfs usertests echo cat README
|
fs.img : mkfs userfs usertests echo cat README init sh
|
||||||
./mkfs fs.img usertests echo cat README
|
./mkfs fs.img userfs usertests echo cat README init sh
|
||||||
|
|
||||||
-include *.d
|
-include *.d
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
rm -f *.o *.d *.asm vectors.S parport.out \
|
rm -f *.o *.d *.asm vectors.S parport.out \
|
||||||
bootblock kernel xv6.img user1 userfs usertests \
|
bootblock kernel xv6.img user1 userfs usertests \
|
||||||
fs.img mkfs echo
|
fs.img mkfs echo init
|
||||||
|
|
32
console.c
32
console.c
|
@ -169,15 +169,14 @@ panic(char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
console_write (int minor, void *buf, int n)
|
console_write (int minor, char *buf, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uchar *b = buf;
|
|
||||||
|
|
||||||
acquire(&console_lock);
|
acquire(&console_lock);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
cons_putc((int) b[i]);
|
cons_putc(buf[i] & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
release(&console_lock);
|
release(&console_lock);
|
||||||
|
@ -349,6 +348,7 @@ kbd_intr()
|
||||||
kbd_buf[kbd_w++] = c;
|
kbd_buf[kbd_w++] = c;
|
||||||
if(kbd_w >= KBD_BUF)
|
if(kbd_w >= KBD_BUF)
|
||||||
kbd_w = 0;
|
kbd_w = 0;
|
||||||
|
wakeup(&kbd_r);
|
||||||
} else {
|
} else {
|
||||||
cprintf("kbd overflow\n");
|
cprintf("kbd overflow\n");
|
||||||
}
|
}
|
||||||
|
@ -356,6 +356,31 @@ kbd_intr()
|
||||||
release(&kbd_lock);
|
release(&kbd_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
console_read(int minor, char *dst, int n)
|
||||||
|
{
|
||||||
|
uint target = n;
|
||||||
|
|
||||||
|
acquire(&kbd_lock);
|
||||||
|
|
||||||
|
while(kbd_w == kbd_r)
|
||||||
|
sleep(&kbd_r, &kbd_lock);
|
||||||
|
|
||||||
|
while(n > 0 && kbd_w != kbd_r){
|
||||||
|
*dst = kbd_buf[kbd_r];
|
||||||
|
cons_putc(*dst & 0xff);
|
||||||
|
dst++;
|
||||||
|
--n;
|
||||||
|
kbd_r++;
|
||||||
|
if(kbd_r >= KBD_BUF)
|
||||||
|
kbd_r = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
release(&kbd_lock);
|
||||||
|
|
||||||
|
return target - n;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
console_init()
|
console_init()
|
||||||
{
|
{
|
||||||
|
@ -363,6 +388,7 @@ console_init()
|
||||||
initlock(&kbd_lock, "kbd");
|
initlock(&kbd_lock, "kbd");
|
||||||
|
|
||||||
devsw[CONSOLE].d_write = console_write;
|
devsw[CONSOLE].d_write = console_write;
|
||||||
|
devsw[CONSOLE].d_read = console_read;
|
||||||
|
|
||||||
ioapic_enable (IRQ_KBD, 1);
|
ioapic_enable (IRQ_KBD, 1);
|
||||||
|
|
||||||
|
|
5
defs.h
5
defs.h
|
@ -115,6 +115,7 @@ void iunlock(struct inode *ip);
|
||||||
void idecref(struct inode *ip);
|
void idecref(struct inode *ip);
|
||||||
void iput(struct inode *ip);
|
void iput(struct inode *ip);
|
||||||
struct inode * namei(char *path);
|
struct inode * namei(char *path);
|
||||||
int readi(struct inode *ip, void *xdst, uint off, uint n);
|
int readi(struct inode *ip, char *xdst, uint off, uint n);
|
||||||
int writei(struct inode *ip, void *addr, uint off, uint n);
|
int writei(struct inode *ip, char *addr, uint off, uint n);
|
||||||
struct inode *mknod(struct inode *, char *, short, short, short);
|
struct inode *mknod(struct inode *, char *, short, short, short);
|
||||||
|
void iupdate (struct inode *ip);
|
||||||
|
|
4
dev.h
4
dev.h
|
@ -1,7 +1,7 @@
|
||||||
struct devsw {
|
struct devsw {
|
||||||
int (*d_open)(char *, int);
|
int (*d_open)(char *, int);
|
||||||
int (*d_read)(int, void *, int);
|
int (*d_read)(int, char *, int);
|
||||||
int (*d_write)(int, void *, int);
|
int (*d_write)(int, char *, int);
|
||||||
int (*d_close)(int);
|
int (*d_close)(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
11
fs.c
11
fs.c
|
@ -101,6 +101,7 @@ iget(uint dev, uint inum)
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
ip->count++;
|
ip->count++;
|
||||||
|
ip->busy = 1;
|
||||||
release(&inode_table_lock);
|
release(&inode_table_lock);
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
@ -269,16 +270,15 @@ bmap(struct inode *ip, uint bn)
|
||||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
int
|
int
|
||||||
readi(struct inode *ip, void *xdst, uint off, uint n)
|
readi(struct inode *ip, char *dst, uint off, uint n)
|
||||||
{
|
{
|
||||||
char *dst = (char *) xdst;
|
|
||||||
uint target = n, n1;
|
uint target = n, n1;
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
|
||||||
if (ip->type == T_DEV) {
|
if (ip->type == T_DEV) {
|
||||||
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_read)
|
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_read)
|
||||||
return -1;
|
return -1;
|
||||||
return devsw[ip->major].d_read (ip->minor, xdst, n);
|
return devsw[ip->major].d_read (ip->minor, dst, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(n > 0 && off < ip->size){
|
while(n > 0 && off < ip->size){
|
||||||
|
@ -298,7 +298,7 @@ readi(struct inode *ip, void *xdst, uint off, uint n)
|
||||||
#define MIN(a, b) ((a < b) ? a : b)
|
#define MIN(a, b) ((a < b) ? a : b)
|
||||||
|
|
||||||
int
|
int
|
||||||
writei(struct inode *ip, void *addr, uint off, uint n)
|
writei(struct inode *ip, char *addr, uint off, uint n)
|
||||||
{
|
{
|
||||||
if (ip->type == T_DEV) {
|
if (ip->type == T_DEV) {
|
||||||
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write)
|
if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].d_write)
|
||||||
|
@ -404,7 +404,8 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
|
||||||
int i;
|
int i;
|
||||||
struct buf *bp = 0;
|
struct buf *bp = 0;
|
||||||
|
|
||||||
cprintf("mknod: %s %d %d %d\n", cp, type, major, minor);
|
cprintf("mknod: dir %d %s %d %d %d\n",
|
||||||
|
dp->inum, cp, type, major, minor);
|
||||||
|
|
||||||
ip = ialloc(dp->dev, type);
|
ip = ialloc(dp->dev, type);
|
||||||
if (ip == 0) return 0;
|
if (ip == 0) return 0;
|
||||||
|
|
32
init.c
Normal file
32
init.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "user.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "fcntl.h"
|
||||||
|
|
||||||
|
char *sh_args[] = { "sh", 0 };
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
if(open("console", 0) < 0){
|
||||||
|
mknod("console", T_DEV, 1, 1);
|
||||||
|
open("console", 0);
|
||||||
|
}
|
||||||
|
open("console", 1);
|
||||||
|
open("console", 1);
|
||||||
|
|
||||||
|
write(1, "init...\n", 8);
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
write(1, "running sh...\n", 14);
|
||||||
|
pid = fork();
|
||||||
|
if(pid == 0){
|
||||||
|
exec("sh", sh_args);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if(pid > 0)
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
8
main.c
8
main.c
|
@ -11,9 +11,8 @@
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
|
|
||||||
extern char edata[], end[];
|
extern char edata[], end[];
|
||||||
extern uchar _binary_user1_start[], _binary_user1_size[];
|
|
||||||
extern uchar _binary_usertests_start[], _binary_usertests_size[];
|
|
||||||
extern uchar _binary_userfs_start[], _binary_userfs_size[];
|
extern uchar _binary_userfs_start[], _binary_userfs_size[];
|
||||||
|
extern uchar _binary_init_start[], _binary_init_size[];
|
||||||
|
|
||||||
// CPU 0 starts running C code here.
|
// CPU 0 starts running C code here.
|
||||||
// This is called main0 not main so that it can have
|
// This is called main0 not main so that it can have
|
||||||
|
@ -96,9 +95,10 @@ main0(void)
|
||||||
p = copyproc(&proc[0]);
|
p = copyproc(&proc[0]);
|
||||||
|
|
||||||
//load_icode(p, _binary_usertests_start, (uint) _binary_usertests_size);
|
//load_icode(p, _binary_usertests_start, (uint) _binary_usertests_size);
|
||||||
load_icode(p, _binary_userfs_start, (uint) _binary_userfs_size);
|
//load_icode(p, _binary_userfs_start, (uint) _binary_userfs_size);
|
||||||
|
load_icode(p, _binary_init_start, (uint) _binary_init_size);
|
||||||
p->state = RUNNABLE;
|
p->state = RUNNABLE;
|
||||||
cprintf("loaded userfs\n");
|
cprintf("loaded init\n");
|
||||||
|
|
||||||
scheduler();
|
scheduler();
|
||||||
}
|
}
|
||||||
|
|
31
sh.c
Normal file
31
sh.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "user.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "fcntl.h"
|
||||||
|
|
||||||
|
char *args[100];
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
char buf[128];
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
write(1, "$ ", 2);
|
||||||
|
gets(buf, sizeof(buf));
|
||||||
|
if(buf[0] == '\0')
|
||||||
|
continue;
|
||||||
|
pid = fork();
|
||||||
|
if(pid == 0){
|
||||||
|
args[0] = buf;
|
||||||
|
args[1] = 0;
|
||||||
|
exec(buf, args);
|
||||||
|
write(1, buf, strlen(buf));
|
||||||
|
write(1, ": not found\n", 12);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if(pid > 0)
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
19
syscall.c
19
syscall.c
|
@ -319,14 +319,19 @@ sys_mknod(void)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
dp = iget(rootdev, 1); // XXX should parse name
|
dp = iget(rootdev, 1); // XXX should parse name
|
||||||
if (dp->type != T_DIR)
|
if (dp->type != T_DIR) {
|
||||||
|
iput(dp);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2,
|
nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2,
|
||||||
(short) arg3);
|
(short) arg3);
|
||||||
|
|
||||||
if (nip == 0) return -1;
|
|
||||||
iput(nip);
|
|
||||||
iput(dp);
|
iput(dp);
|
||||||
|
|
||||||
|
if (nip == 0) return -1;
|
||||||
|
|
||||||
|
iput(nip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -376,7 +381,7 @@ sys_exec(void)
|
||||||
if(ip == 0)
|
if(ip == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(readi(ip, &elf, 0, sizeof(elf)) < sizeof(elf))
|
if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if(elf.magic != ELF_MAGIC)
|
if(elf.magic != ELF_MAGIC)
|
||||||
|
@ -384,7 +389,8 @@ sys_exec(void)
|
||||||
|
|
||||||
sz = 0;
|
sz = 0;
|
||||||
for(i = 0; i < elf.phnum; i++){
|
for(i = 0; i < elf.phnum; i++){
|
||||||
if(readi(ip, &ph, elf.phoff + i * sizeof(ph), sizeof(ph)) != sizeof(ph))
|
if(readi(ip, (char*)&ph, elf.phoff + i * sizeof(ph),
|
||||||
|
sizeof(ph)) != sizeof(ph))
|
||||||
goto bad;
|
goto bad;
|
||||||
if(ph.type != ELF_PROG_LOAD)
|
if(ph.type != ELF_PROG_LOAD)
|
||||||
continue;
|
continue;
|
||||||
|
@ -450,7 +456,8 @@ sys_exec(void)
|
||||||
mem = 0;
|
mem = 0;
|
||||||
|
|
||||||
for(i = 0; i < elf.phnum; i++){
|
for(i = 0; i < elf.phnum; i++){
|
||||||
if(readi(ip, &ph, elf.phoff + i * sizeof(ph), sizeof(ph)) != sizeof(ph))
|
if(readi(ip, (char*)&ph, elf.phoff + i * sizeof(ph),
|
||||||
|
sizeof(ph)) != sizeof(ph))
|
||||||
goto bad2;
|
goto bad2;
|
||||||
if(ph.type != ELF_PROG_LOAD)
|
if(ph.type != ELF_PROG_LOAD)
|
||||||
continue;
|
continue;
|
||||||
|
|
39
ulib.c
39
ulib.c
|
@ -3,17 +3,7 @@
|
||||||
int
|
int
|
||||||
puts(char *s)
|
puts(char *s)
|
||||||
{
|
{
|
||||||
return cons_puts(s);
|
return write(1, s, strlen(s));
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
puts1(char *s)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; s[i]; i++)
|
|
||||||
cons_putc(s[i]);
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
|
@ -26,3 +16,30 @@ strcpy(char *s, char *t)
|
||||||
;
|
;
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
strlen(char *s)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
for(n = 0; s[n]; n++)
|
||||||
|
;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
gets(char *buf, int max)
|
||||||
|
{
|
||||||
|
int i = 0, cc;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while(i+1 < max){
|
||||||
|
cc = read(0, &c, 1);
|
||||||
|
if(cc < 1)
|
||||||
|
break;
|
||||||
|
if(c == '\n' || c == '\r')
|
||||||
|
break;
|
||||||
|
buf[i++] = c;
|
||||||
|
}
|
||||||
|
buf[i] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
5
user.h
5
user.h
|
@ -14,8 +14,9 @@ int exec(char *, char **);
|
||||||
int open(char *, int);
|
int open(char *, int);
|
||||||
int mknod (char*,short,short,short);
|
int mknod (char*,short,short,short);
|
||||||
int unlink (char*);
|
int unlink (char*);
|
||||||
|
|
||||||
int puts(char*);
|
int puts(char*);
|
||||||
int puts1(char*);
|
|
||||||
char* strcpy(char*, char*);
|
char* strcpy(char*, char*);
|
||||||
void printf(int fd, char *fmt, ...);
|
void printf(int fd, char *fmt, ...);
|
||||||
|
char *gets(char *, int max);
|
||||||
|
unsigned int strlen(char *);
|
||||||
|
|
Loading…
Reference in a new issue