19 |
*/ |
*/ |
20 |
|
|
21 |
#include <pupa/kernel.h> |
#include <pupa/kernel.h> |
22 |
|
#include <pupa/rescue.h> |
23 |
#include <pupa/term.h> |
#include <pupa/term.h> |
24 |
#include <pupa/misc.h> |
#include <pupa/misc.h> |
25 |
#include <pupa/disk.h> |
#include <pupa/disk.h> |
27 |
#include <pupa/mm.h> |
#include <pupa/mm.h> |
28 |
#include <pupa/err.h> |
#include <pupa/err.h> |
29 |
#include <pupa/loader.h> |
#include <pupa/loader.h> |
30 |
|
#include <pupa/dl.h> |
31 |
#include <pupa/machine/partition.h> |
#include <pupa/machine/partition.h> |
32 |
|
|
33 |
#define PUPA_RESCUE_BUF_SIZE 256 |
#define PUPA_RESCUE_BUF_SIZE 256 |
42 |
}; |
}; |
43 |
typedef struct pupa_rescue_command *pupa_rescue_command_t; |
typedef struct pupa_rescue_command *pupa_rescue_command_t; |
44 |
|
|
45 |
static char buf[PUPA_RESCUE_BUF_SIZE]; |
static char linebuf[PUPA_RESCUE_BUF_SIZE]; |
46 |
|
|
47 |
static pupa_rescue_command_t pupa_rescue_command_list; |
static pupa_rescue_command_t pupa_rescue_command_list; |
48 |
|
|
87 |
int pos = 0; |
int pos = 0; |
88 |
|
|
89 |
pupa_printf (prompt); |
pupa_printf (prompt); |
90 |
pupa_memset (buf, 0, PUPA_RESCUE_BUF_SIZE); |
pupa_memset (linebuf, 0, PUPA_RESCUE_BUF_SIZE); |
91 |
|
|
92 |
while ((c = PUPA_TERM_ASCII_CHAR (pupa_getkey ())) != '\n' && c != '\r') |
while ((c = PUPA_TERM_ASCII_CHAR (pupa_getkey ())) != '\n' && c != '\r') |
93 |
{ |
{ |
95 |
{ |
{ |
96 |
if (pos < PUPA_RESCUE_BUF_SIZE - 1) |
if (pos < PUPA_RESCUE_BUF_SIZE - 1) |
97 |
{ |
{ |
98 |
buf[pos++] = c; |
linebuf[pos++] = c; |
99 |
pupa_putchar (c); |
pupa_putchar (c); |
100 |
} |
} |
101 |
} |
} |
103 |
{ |
{ |
104 |
if (pos > 0) |
if (pos > 0) |
105 |
{ |
{ |
106 |
buf[--pos] = 0; |
linebuf[--pos] = 0; |
107 |
pupa_putchar (c); |
pupa_putchar (c); |
108 |
pupa_putchar (' '); |
pupa_putchar (' '); |
109 |
pupa_putchar (c); |
pupa_putchar (c); |
477 |
} |
} |
478 |
#endif |
#endif |
479 |
|
|
480 |
|
/* dump ADDRESS [SIZE] */ |
481 |
static void |
static void |
482 |
pupa_rescue_cmd_dump (int argc, char *argv[]) |
pupa_rescue_cmd_dump (int argc, char *argv[]) |
483 |
{ |
{ |
504 |
} |
} |
505 |
} |
} |
506 |
|
|
507 |
|
/* prefix [DIR] */ |
508 |
|
static void |
509 |
|
pupa_rescue_cmd_prefix (int argc, char *argv[]) |
510 |
|
{ |
511 |
|
static char prefix[100]; |
512 |
|
|
513 |
|
if (argc == 0) |
514 |
|
pupa_printf ("%s\n", pupa_dl_get_prefix ()); |
515 |
|
else |
516 |
|
{ |
517 |
|
if (pupa_strlen (argv[0]) >= sizeof (prefix)) |
518 |
|
{ |
519 |
|
pupa_error (PUPA_ERR_BAD_ARGUMENT, "too long prefix"); |
520 |
|
return; |
521 |
|
} |
522 |
|
|
523 |
|
pupa_strcpy (prefix, argv[0]); |
524 |
|
pupa_dl_set_prefix (prefix); |
525 |
|
} |
526 |
|
} |
527 |
|
|
528 |
|
/* insmod MODULE */ |
529 |
|
static void |
530 |
|
pupa_rescue_cmd_insmod (int argc, char *argv[]) |
531 |
|
{ |
532 |
|
char *p; |
533 |
|
pupa_dl_t mod; |
534 |
|
|
535 |
|
if (argc == 0) |
536 |
|
{ |
537 |
|
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no module specified"); |
538 |
|
return; |
539 |
|
} |
540 |
|
|
541 |
|
p = pupa_strchr (argv[0], '/'); |
542 |
|
if (! p) |
543 |
|
mod = pupa_dl_load (argv[0]); |
544 |
|
else |
545 |
|
mod = pupa_dl_load_file (argv[0]); |
546 |
|
|
547 |
|
if (mod) |
548 |
|
pupa_dl_ref (mod); |
549 |
|
} |
550 |
|
|
551 |
|
/* rmmod MODULE */ |
552 |
|
static void |
553 |
|
pupa_rescue_cmd_rmmod (int argc, char *argv[]) |
554 |
|
{ |
555 |
|
pupa_dl_t mod; |
556 |
|
|
557 |
|
if (argc == 0) |
558 |
|
{ |
559 |
|
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no module specified"); |
560 |
|
return; |
561 |
|
} |
562 |
|
|
563 |
|
mod = pupa_dl_get (argv[0]); |
564 |
|
if (! mod) |
565 |
|
{ |
566 |
|
pupa_error (PUPA_ERR_BAD_ARGUMENT, "no such module"); |
567 |
|
return; |
568 |
|
} |
569 |
|
|
570 |
|
pupa_dl_unref (mod); |
571 |
|
} |
572 |
|
|
573 |
|
/* lsmod */ |
574 |
|
static void |
575 |
|
pupa_rescue_cmd_lsmod (int argc __attribute__ ((unused)), |
576 |
|
char *argv[] __attribute__ ((unused))) |
577 |
|
{ |
578 |
|
auto int print_module (pupa_dl_t mod); |
579 |
|
|
580 |
|
int print_module (pupa_dl_t mod) |
581 |
|
{ |
582 |
|
pupa_dl_dep_t dep; |
583 |
|
|
584 |
|
pupa_printf ("%s\t%d\t\t", mod->name, mod->ref_count); |
585 |
|
for (dep = mod->dep; dep; dep = dep->next) |
586 |
|
{ |
587 |
|
if (dep != mod->dep) |
588 |
|
pupa_putchar (','); |
589 |
|
|
590 |
|
pupa_printf ("%s", dep->mod->name); |
591 |
|
} |
592 |
|
pupa_putchar ('\n'); |
593 |
|
return 0; |
594 |
|
} |
595 |
|
|
596 |
|
pupa_printf ("Name\tRef Count\tDependencies\n"); |
597 |
|
pupa_dl_iterate (print_module); |
598 |
|
} |
599 |
|
|
600 |
/* Enter the rescue mode. */ |
/* Enter the rescue mode. */ |
601 |
void |
void |
602 |
pupa_enter_rescue_mode (void) |
pupa_enter_rescue_mode (void) |
614 |
pupa_rescue_register_command ("module", pupa_rescue_cmd_module, |
pupa_rescue_register_command ("module", pupa_rescue_cmd_module, |
615 |
"load an OS module"); |
"load an OS module"); |
616 |
pupa_rescue_register_command ("root", pupa_rescue_cmd_root, |
pupa_rescue_register_command ("root", pupa_rescue_cmd_root, |
617 |
"set a root device"); |
"set the root device"); |
618 |
pupa_rescue_register_command ("dump", pupa_rescue_cmd_dump, |
pupa_rescue_register_command ("dump", pupa_rescue_cmd_dump, |
619 |
"dump memory"); |
"dump memory"); |
620 |
|
pupa_rescue_register_command ("prefix", pupa_rescue_cmd_prefix, |
621 |
|
"set the prefix"); |
622 |
|
pupa_rescue_register_command ("insmod", pupa_rescue_cmd_insmod, |
623 |
|
"insert a module"); |
624 |
|
pupa_rescue_register_command ("rmmod", pupa_rescue_cmd_rmmod, |
625 |
|
"remove a module"); |
626 |
|
pupa_rescue_register_command ("lsmod", pupa_rescue_cmd_lsmod, |
627 |
|
"show loaded modules"); |
628 |
|
|
629 |
while (1) |
while (1) |
630 |
{ |
{ |
631 |
char *line = buf; |
char *line = linebuf; |
632 |
char *name; |
char *name; |
633 |
int n; |
int n; |
634 |
pupa_rescue_command_t cmd; |
pupa_rescue_command_t cmd; |