Add debugging kernel monitor functions
This commit is contained in:
parent
0fe97e52c3
commit
7d76204053
|
@ -7,6 +7,7 @@
|
||||||
#include <inc/assert.h>
|
#include <inc/assert.h>
|
||||||
#include <inc/x86.h>
|
#include <inc/x86.h>
|
||||||
|
|
||||||
|
#include <kern/env.h>
|
||||||
#include <kern/ansi.h>
|
#include <kern/ansi.h>
|
||||||
#include <kern/console.h>
|
#include <kern/console.h>
|
||||||
#include <kern/monitor.h>
|
#include <kern/monitor.h>
|
||||||
|
@ -31,7 +32,9 @@ static struct Command commands[] = {
|
||||||
{ "kerninfo", "Display information about the kernel", mon_kerninfo },
|
{ "kerninfo", "Display information about the kernel", mon_kerninfo },
|
||||||
{ "backtrace", "Display current backtrace", mon_backtrace },
|
{ "backtrace", "Display current backtrace", mon_backtrace },
|
||||||
{ "showmappings", "Display the physical mappings for range", mon_showmappings },
|
{ "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;
|
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 *****/
|
/***** Kernel monitor command interpreter *****/
|
||||||
|
|
||||||
#define WHITESPACE "\t\r\n "
|
#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_backtrace(int argc, char **argv, struct Trapframe *tf);
|
||||||
int mon_showmappings(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_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
|
#endif // !JOS_KERN_MONITOR_H
|
||||||
|
|
|
@ -199,7 +199,7 @@ trap_dispatch(struct Trapframe *tf)
|
||||||
if (tf->tf_trapno == T_PGFLT) {
|
if (tf->tf_trapno == T_PGFLT) {
|
||||||
page_fault_handler(tf);
|
page_fault_handler(tf);
|
||||||
return;
|
return;
|
||||||
} else if (tf->tf_trapno == T_BRKPT) {
|
} else if (tf->tf_trapno == T_BRKPT || tf->tf_trapno == T_DEBUG) {
|
||||||
monitor(tf);
|
monitor(tf);
|
||||||
return;
|
return;
|
||||||
} else if (tf->tf_trapno == T_SYSCALL) {
|
} else if (tf->tf_trapno == T_SYSCALL) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user