diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/console.c | 101 | ||||
| -rw-r--r-- | kernel/main.c | 1 | ||||
| -rw-r--r-- | kernel/proc.c | 1 | 
3 files changed, 68 insertions, 35 deletions
| diff --git a/kernel/console.c b/kernel/console.c index 8023405..650e2af 100644 --- a/kernel/console.c +++ b/kernel/console.c @@ -1,6 +1,12 @@  //  // Console input and output, to the uart. -// Implements erase/kill processing. +// Reads are line at a time. +// Implements special input characters: +//   newline -- end of line +//   control-h -- backspace +//   control-u -- kill line +//   control-d -- end of file +//   control-p -- print process list  //  #include <stdarg.h> @@ -17,7 +23,11 @@  #include "proc.h"  #define BACKSPACE 0x100 +#define C(x)  ((x)-'@')  // Control-x +// +// send one character to the uart. +//  void  consputc(int c)  { @@ -29,9 +39,11 @@ consputc(int c)    }    if(c == BACKSPACE){ +    // if the user typed backspace, erase the character.      uartputc('\b'); uartputc(' '); uartputc('\b'); -  } else +  } else {      uartputc(c); +  }  }  struct { @@ -45,18 +57,44 @@ struct {    uint e;  // Edit index  } cons; -#define C(x)  ((x)-'@')  // Contro +// +// user write()s to the console go here. +// +int +consolewrite(int user_src, uint64 src, int n) +{ +  int i; +  acquire(&cons.lock); +  for(i = 0; i < n; i++){ +    char c; +    if(either_copyin(&c, user_src, src+i, 1) == -1) +      break; +    consputc(c); +  } +  release(&cons.lock); + +  return n; +} + +// +// user read()s from the console go here. +// copy (up to) a whole input line to dst. +// user_dist indicates whether dst is a user +// or kernel address. +//  int  consoleread(int user_dst, uint64 dst, int n)  {    uint target;    int c; -  char buf[1]; +  char cbuf;    target = n;    acquire(&cons.lock);    while(n > 0){ +    // wait until interrupt handler has put some +    // input into cons.buffer.      while(cons.r == cons.w){        if(myproc()->killed){          release(&cons.lock); @@ -64,8 +102,10 @@ consoleread(int user_dst, uint64 dst, int n)        }        sleep(&cons.r, &cons.lock);      } +      c = cons.buf[cons.r++ % INPUT_BUF]; -    if(c == C('D')){  // EOF + +    if(c == C('D')){  // end-of-file        if(n < target){          // Save ^D for next time, to make sure          // caller gets a 0-byte result. @@ -73,47 +113,40 @@ consoleread(int user_dst, uint64 dst, int n)        }        break;      } -    buf[0] = c; -    if(either_copyout(user_dst, dst, &buf[0], 1) == -1) + +    // copy the input byte to the user-space buffer. +    cbuf = c; +    if(either_copyout(user_dst, dst, &cbuf, 1) == -1)        break; +      dst++;      --n; -    if(c == '\n') -      break; -  } -  release(&cons.lock); -  return target - n; -} - -int -consolewrite(int user_src, uint64 src, int n) -{ -  int i; - -  acquire(&cons.lock); -  for(i = 0; i < n; i++){ -    char c; -    if(either_copyin(&c, user_src, src+i, 1) == -1) +    if(c == '\n'){ +      // a whole line has arrived, return to +      // the user-level read().        break; -    consputc(c); +    }    }    release(&cons.lock); -  return n; +  return target - n;  } +// +// the uart interrupt handler, uartintr(), calls this +// for each input character. do erase/kill processing, +// append to cons.buf, wake up reader if a whole +// line has arrived. +//  void  consoleintr(int c)  { -  int doprocdump = 0; -      acquire(&cons.lock);    switch(c){ -  case C('P'):  // Process list. -    // procdump() locks cons.lock indirectly; invoke later -    doprocdump = 1; +  case C('P'):  // Print process list. +    procdump();      break;    case C('U'):  // Kill line.      while(cons.e != cons.w && @@ -122,7 +155,8 @@ consoleintr(int c)        consputc(BACKSPACE);      }      break; -  case C('H'): case '\x7f':  // Backspace +  case C('H'): // Backspace +  case '\x7f':      if(cons.e != cons.w){        cons.e--;        consputc(BACKSPACE); @@ -142,9 +176,6 @@ consoleintr(int c)    }    release(&cons.lock); - -  if(doprocdump) -    procdump();  }  void @@ -152,6 +183,8 @@ consoleinit(void)  {    initlock(&cons.lock, "cons"); +  uartinit(); +    devsw[CONSOLE].write = consolewrite;    devsw[CONSOLE].read = consoleread;  } diff --git a/kernel/main.c b/kernel/main.c index 09580e0..efdf277 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -11,7 +11,6 @@ void  main()  {    if(cpuid() == 0){ -    uartinit();      // serial port      consoleinit();      printfinit();      printf("hart %d starting\n", cpuid()); diff --git a/kernel/proc.c b/kernel/proc.c index 0dcae00..1f6bfcc 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -634,6 +634,7 @@ procdump(void)    struct proc *p;    char *state; +  printf("\n");    for(p = proc; p < &proc[NPROC]; p++){      if(p->state == UNUSED)        continue; | 
