Add debugging kernel monitor functions
This commit is contained in:
parent
0fe97e52c3
commit
7d76204053
@ -7,6 +7,7 @@
|
||||
#include <inc/assert.h>
|
||||
#include <inc/x86.h>
|
||||
|
||||
#include <kern/env.h>
|
||||
#include <kern/ansi.h>
|
||||
#include <kern/console.h>
|
||||
#include <kern/monitor.h>
|
||||
@ -31,7 +32,9 @@ static struct Command commands[] = {
|
||||
{ "kerninfo", "Display information about the kernel", mon_kerninfo },
|
||||
{ "backtrace", "Display current backtrace", mon_backtrace },
|
||||
{ "showmappings", "Display the physical mappings for range", mon_showmappings },
|
||||
{ "mperms", "Change the permissions of a memory range", mon_mperms }
|
||||
{ "mperms", "Change the permissions of a memory range", mon_mperms },
|
||||
{ "resume", "Resume from a breakpoint", mon_resume },
|
||||
{ "step", "Step to next instruction", mon_step }
|
||||
|
||||
};
|
||||
|
||||
@ -188,6 +191,43 @@ int mon_mperms(int argc, char** argv, struct Trapframe* tf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is a nice thought and all...
|
||||
// But we should modify the trap frame.
|
||||
// I feel stupid.
|
||||
static inline void
|
||||
set_eflag(uint16_t flagno, int value) {
|
||||
uint32_t temp;
|
||||
uint32_t mask = ~(1 << flagno);
|
||||
uint32_t regv = value << flagno;
|
||||
asm volatile("pushfl\n\t"
|
||||
"pop %w0\n\t"
|
||||
"and %w1, %w0\n\t"
|
||||
"or %w2, %w0\n\t"
|
||||
"push %w0\n\t"
|
||||
"popfl\n\t"
|
||||
: "=r" (temp)
|
||||
: "r" (mask), "r" (regv));
|
||||
}
|
||||
|
||||
#define EXPECT_BRKPT if(!(tf->tf_trapno == T_BRKPT || tf->tf_trapno == T_DEBUG)) { \
|
||||
cprintf(ACOL_ERR("I don't think I should resume from this.\n")); \
|
||||
return 0; }
|
||||
#define EFLAGS_TF 0x8
|
||||
|
||||
int mon_resume(int argc, char** argv, struct Trapframe* tf) {
|
||||
EXPECT_BRKPT;
|
||||
tf->tf_eflags &= ~(1 << EFLAGS_TF);
|
||||
env_pop_tf(tf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mon_step(int argc, char** argv, struct Trapframe* tf) {
|
||||
EXPECT_BRKPT;
|
||||
tf->tf_eflags |= 1 << EFLAGS_TF;
|
||||
env_pop_tf(tf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***** Kernel monitor command interpreter *****/
|
||||
|
||||
#define WHITESPACE "\t\r\n "
|
||||
|
@ -17,5 +17,7 @@ int mon_kerninfo(int argc, char **argv, struct Trapframe *tf);
|
||||
int mon_backtrace(int argc, char **argv, struct Trapframe *tf);
|
||||
int mon_showmappings(int argc, char **argv, struct Trapframe *tf);
|
||||
int mon_mperms(int argc, char** argv, struct Trapframe* tf);
|
||||
int mon_resume(int argc, char** argv, struct Trapframe* tf);
|
||||
int mon_step(int argc, char** argv, struct Trapframe* tf);
|
||||
|
||||
#endif // !JOS_KERN_MONITOR_H
|
||||
|
@ -199,7 +199,7 @@ trap_dispatch(struct Trapframe *tf)
|
||||
if (tf->tf_trapno == T_PGFLT) {
|
||||
page_fault_handler(tf);
|
||||
return;
|
||||
} else if (tf->tf_trapno == T_BRKPT) {
|
||||
} else if (tf->tf_trapno == T_BRKPT || tf->tf_trapno == T_DEBUG) {
|
||||
monitor(tf);
|
||||
return;
|
||||
} else if (tf->tf_trapno == T_SYSCALL) {
|
||||
|
Loading…
Reference in New Issue
Block a user