menuentry "$_OS_NAME" {
multiboot /boot/kernel.bin
- module /boot/modksyms modksyms
+ module --nounzip /boot/modksyms modksyms
}
\ No newline at end of file
*/
.section .text
+ .type interrupt_wrapper, @function
.global interrupt_wrapper
interrupt_wrapper:
cld
subl $16, %esp
movl %eax, (%esp)
+ xorl %ebp, %ebp # marks the boundary of stack walking
call intr_handler
movl (%esp), %eax
iret
+ .type switch_to, @function
.global switch_to
switch_to:
# 约定
movl proc_intr_ctx(%ebx), %eax
jmp soft_iret
+ .type handle_signal, @function
.global handle_signal
handle_signal:
# 注意1:任何对proc_sig的布局改动,都须及时的保证这里的一致性!
#include <sys/interrupts.h>
#include <sys/x86_isa.h>
-#include <hal/cpu.h>
+#include <sys/cpu.h>
#include <hal/intc.h>
#include <lunaix/isrm.h>
#include <lunaix/sched.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
+#include <lunaix/trace.h>
#include <lunaix/tty/tty.h>
#include <klibc/stdio.h>
void
__print_panic_msg(const char* msg, const isr_param* param)
{
- volatile struct exec_param* execp = param->execp;
-
- kprint_panic(" INT %u: (%x) [%p: %p] %s",
- execp->vector,
- execp->err_code,
- execp->cs,
- execp->eip,
- msg);
+ kprintf(KERROR "panic: %s\n", msg);
+ trace_printstack_isr(param);
}
void
intr_routine_divide_zero(const isr_param* param)
{
+ __print_panic_msg("div zero", param);
+
console_flush();
- __print_panic_msg("Divide by zero!", param);
spin();
}
void
intr_routine_general_protection(const isr_param* param)
{
- kprintf(KERROR "Pid: %d\n", __current->pid);
- kprintf(KERROR "Addr: %p\n", (&debug_resv)[0]);
- kprintf(KERROR "Expected: %p\n", (&debug_resv)[1]);
+ __print_panic_msg("general protection", param);
+
console_flush();
- __print_panic_msg("General Protection", param);
spin();
}
void
intr_routine_sys_panic(const isr_param* param)
{
- console_flush();
__print_panic_msg((char*)(param->registers.edi), param);
+
+ console_flush();
spin();
}
void
intr_routine_fallback(const isr_param* param)
{
- __print_panic_msg("Unknown Interrupt", param);
+ __print_panic_msg("unknown interrupt", param);
+
console_flush();
spin();
}
u32_t error_reg = apic_read_reg(APIC_ESR);
char buf[32];
ksprintf(buf, "APIC error, ESR=0x%x", error_reg);
- console_flush();
+
__print_panic_msg(buf, param);
+
+ console_flush();
spin();
}
*
*/
-#include <hal/cpu.h>
+#include <sys/cpu.h>
#include <hal/intc.h>
#include <sys/apic.h>
-#include <sys/vectors.h>
#include <cpuid.h>
-#include <hal/cpu.h>
#include <lunaix/types.h>
+#include <sys/cpu.h>
+#include <sys/vectors.h>
#define BRAND_LEAF 0x80000000UL
id_out[48] = '\0';
}
-u32_t
-cpu_ldstate()
-{
- ptr_t val;
- asm volatile("pushf\n"
- "popl %0\n"
- : "=r"(val)::);
- return val;
-}
-
-u32_t
-cpu_ldconfig()
-{
- ptr_t val;
- asm volatile("movl %%cr0,%0" : "=r"(val));
- return val;
-}
-
-void
-cpu_chconfig(u32_t val)
-{
- asm("mov %0, %%cr0" ::"r"(val));
-}
-
-u32_t
-cpu_ldvmspace()
-{
- ptr_t val;
- asm volatile("movl %%cr3,%0" : "=r"(val));
- return val;
-}
-
-void
-cpu_chvmspace(u32_t val)
-{
- asm("mov %0, %%cr3" ::"r"(val));
-}
-
-void
-cpu_flush_page(ptr_t va)
-{
- asm volatile("invlpg (%0)" ::"r"(va) : "memory");
-}
-
void
-cpu_flush_vmspace()
+cpu_rdmsr(u32_t msr_idx, u32_t* reg_high, u32_t* reg_low)
{
- asm("movl %%cr3, %%eax\n"
- "movl %%eax, %%cr3" ::
- : "eax");
-}
+ u32_t h = 0, l = 0;
+ asm volatile("rdmsr" : "=d"(h), "=a"(l) : "c"(msr_idx));
-void
-cpu_enable_interrupt()
-{
- asm volatile("sti");
+ *reg_high = h;
+ *reg_low = l;
}
void
-cpu_disable_interrupt()
+cpu_wrmsr(u32_t msr_idx, u32_t reg_high, u32_t reg_low)
{
- asm volatile("cli");
+ asm volatile("wrmsr" : : "d"(reg_high), "a"(reg_low), "c"(msr_idx));
}
void
{
asm("int %0" ::"i"(LUNAIX_SYS_PANIC), "D"(message));
}
-
-void
-cpu_wait()
-{
- asm("hlt");
-}
-
-ptr_t
-cpu_ldeaddr()
-{
- ptr_t val;
- asm volatile("movl %%cr2,%0" : "=r"(val));
- return val;
-}
-
-void
-cpu_rdmsr(u32_t msr_idx, u32_t* reg_high, u32_t* reg_low)
-{
- u32_t h = 0, l = 0;
- asm volatile("rdmsr" : "=d"(h), "=a"(l) : "c"(msr_idx));
-
- *reg_high = h;
- *reg_low = l;
-}
-
-void
-cpu_wrmsr(u32_t msr_idx, u32_t reg_high, u32_t reg_low)
-{
- asm volatile("wrmsr" : : "d"(reg_high), "a"(reg_low), "c"(msr_idx));
-}
\ No newline at end of file
--- /dev/null
+#ifndef __LUNAIX_CPU_H
+#define __LUNAIX_CPU_H
+
+#include <lunaix/types.h>
+
+/**
+ * @brief Get processor ID string
+ *
+ * @param id_out
+ */
+void
+cpu_get_id(char* id_out);
+
+void
+cpu_trap_sched();
+
+void
+cpu_trap_panic(char* message);
+
+static inline ptr_t
+cpu_get_fp()
+{
+ ptr_t val;
+ asm("movl %%ebp, %0" : "=r"(val)::);
+ return val;
+}
+
+/**
+ * @brief Load current processor state
+ *
+ * @return u32_t
+ */
+static inline u32_t
+cpu_ldstate()
+{
+ ptr_t val;
+ asm volatile("pushf\n"
+ "popl %0\n"
+ : "=r"(val)::);
+ return val;
+}
+
+/**
+ * @brief Load current processor config
+ *
+ * @return u32_t
+ */
+static inline u32_t
+cpu_ldconfig()
+{
+ ptr_t val;
+ asm volatile("movl %%cr0,%0" : "=r"(val));
+ return val;
+}
+
+/**
+ * @brief Change current processor state
+ *
+ * @return u32_t
+ */
+static inline void
+cpu_chconfig(u32_t val)
+{
+ asm("mov %0, %%cr0" ::"r"(val));
+}
+
+/**
+ * @brief Load current virtual memory space
+ *
+ * @return u32_t
+ */
+static inline u32_t
+cpu_ldvmspace()
+{
+ ptr_t val;
+ asm volatile("movl %%cr3,%0" : "=r"(val));
+ return val;
+}
+
+/**
+ * @brief Change current virtual memory space
+ *
+ * @return u32_t
+ */
+static inline void
+cpu_chvmspace(u32_t val)
+{
+ asm("mov %0, %%cr3" ::"r"(val));
+}
+
+/**
+ * @brief Flush TLB
+ *
+ * @return u32_t
+ */
+static inline void
+cpu_flush_page(ptr_t va)
+{
+ asm volatile("invlpg (%0)" ::"r"(va) : "memory");
+}
+
+static inline void
+cpu_flush_vmspace()
+{
+ asm("movl %%cr3, %%eax\n"
+ "movl %%eax, %%cr3" ::
+ : "eax");
+}
+
+static inline void
+cpu_enable_interrupt()
+{
+ asm volatile("sti");
+}
+
+static inline void
+cpu_disable_interrupt()
+{
+ asm volatile("cli");
+}
+
+static inline void
+cpu_wait()
+{
+ asm("hlt");
+}
+
+static inline ptr_t
+cpu_ldeaddr()
+{
+ ptr_t val;
+ asm volatile("movl %%cr2,%0" : "=r"(val));
+ return val;
+}
+
+#endif /* __LUNAIX_CPU_H */
#include "vectors.h"
#ifndef __ASM__
-#include <hal/cpu.h>
+#include <sys/cpu.h>
+
+#define saved_fp(isrm) ((isrm)->registers.ebp)
+#define uspace_context(isrm) (((isrm)->execp->cs) == 0x8)
struct exec_param;
#include <lunaix/signal.h>
#include <lunaix/status.h>
#include <lunaix/syslog.h>
+#include <lunaix/trace.h>
+
#include <sys/interrupts.h>
#include <klibc/string.h>
sigset_add(__current->sigctx.sig_pending, _SIGSEGV);
+ trace_printstack_isr(param);
+
schedule();
// should not reach
while (1)
+++ /dev/null
-#ifndef __LUNAIX_CPU_H
-#define __LUNAIX_CPU_H
-
-#include <lunaix/types.h>
-
-/**
- * @brief Get processor ID string
- *
- * @param id_out
- */
-void
-cpu_get_id(char* id_out);
-
-/**
- * @brief Load current processor state
- *
- * @return u32_t
- */
-u32_t
-cpu_ldstate();
-
-/**
- * @brief Load current processor config
- *
- * @return u32_t
- */
-u32_t
-cpu_ldconfig();
-
-/**
- * @brief Change current processor state
- *
- * @return u32_t
- */
-void
-cpu_chconfig(u32_t val);
-
-/**
- * @brief Load current virtual memory space
- *
- * @return u32_t
- */
-u32_t
-cpu_ldvmspace();
-
-/**
- * @brief Change current virtual memory space
- *
- * @return u32_t
- */
-void
-cpu_chvmspace(u32_t val);
-
-/**
- * @brief Flush TLB
- *
- * @return u32_t
- */
-void
-cpu_flush_page(ptr_t va);
-
-void
-cpu_flush_vmspace();
-
-void
-cpu_enable_interrupt();
-
-void
-cpu_disable_interrupt();
-
-void
-cpu_trap_sched();
-
-void
-cpu_trap_panic(char* message);
-
-void
-cpu_wait();
-
-ptr_t
-cpu_ldeaddr();
-
-#endif /* __LUNAIX_CPU_H */
#define __LUNAIX_TRACE_H
#include <lunaix/boot_generic.h>
+#include <sys/interrupts.h>
struct ksym_entry
{
u32_t label_off;
};
+struct trace_record
+{
+ ptr_t pc;
+ char* symbol;
+};
+
struct ksyms
{
u32_t ksym_count;
struct ksym_entry*
trace_sym_lookup(ptr_t pc);
+int
+trace_walkback(struct trace_record* tb_buffer,
+ ptr_t fp,
+ int limit,
+ ptr_t* last_fp);
+
+void
+trace_printstack_of(ptr_t fp);
+
+void
+trace_printstack_isr(const isr_param* isrm);
+
void
-trace_walkback(ptr_t fp);
+trace_printstack();
#endif /* __LUNAIX_TRACE_H */
#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
-#include <hal/cpu.h>
+#include <sys/cpu.h>
static struct cake_pile* blkio_reqpile;
vmm_set_mapping(VMS_SELF, pa, pa, PG_PREM_RW, VMAP_IGNORE);
}
}
+
+ /* Reserve region for all loaded modules */
+ for (size_t i = 0; i < bhctx->mods.mods_num; i++) {
+ struct boot_modent* mod = &bhctx->mods.entries[i];
+ pmm_mark_chunk_occupied(KERNEL_PID,
+ PN(mod->start),
+ CEIL(mod->end - mod->start, PG_SIZE_BITS),
+ PP_FGLOCKED);
+ }
}
extern u8_t __kexec_boot_end; /* link/linker.ld */
#include <lunaix/mm/mmio.h>
#include <lunaix/mm/page.h>
+#include <lunaix/process.h>
#include <lunaix/spike.h>
+#include <lunaix/syslog.h>
#include <lunaix/trace.h>
+#include <sys/cpu.h>
+#include <sys/mm/mempart.h>
+
#include <klibc/string.h>
+#define NB_TRACEBACK 16
+
+LOG_MODULE("TRACE")
+
static struct trace_context trace_ctx;
void
}
struct ksym_entry*
-trace_sym_lookup(ptr_t pc)
+trace_sym_lookup(ptr_t addr)
+{
+ int c = trace_ctx.ksym_table->ksym_count;
+ struct ksym_entry* ksent = trace_ctx.ksym_table->syms;
+
+ int i = c - 1, j = 0, m = 0;
+
+ if (addr > ksent[i].pc || addr < ksent[j].pc || addr < KERNEL_EXEC) {
+ return NULL;
+ }
+
+ while (i - j != 1) {
+ m = (i + j) / 2;
+ if (ksent[m].pc > addr) {
+ i = m;
+ } else if (ksent[m].pc < addr) {
+ j = m;
+ } else {
+ break;
+ }
+ }
+
+ struct ksym_entry* result = &ksent[MIN(i, j)];
+ if (result->pc > addr) {
+ return NULL;
+ }
+
+ return result;
+}
+
+static char*
+ksym_getstr(struct ksym_entry* sym)
+{
+ if (!sym) {
+ return "???";
+ }
+
+ return (char*)((ptr_t)trace_ctx.ksym_table +
+ trace_ctx.ksym_table->ksym_label_off + sym->label_off);
+}
+
+int
+trace_walkback(struct trace_record* tb_buffer,
+ ptr_t fp,
+ int limit,
+ ptr_t* last_fp)
+{
+ ptr_t* frame = (ptr_t*)fp;
+ struct ksym_entry* current = NULL;
+ int i = 0;
+
+ while (frame && i < limit) {
+ ptr_t pc = *(frame + 1);
+
+ current = trace_sym_lookup(pc);
+ tb_buffer[i] = (struct trace_record){ .pc = current ? current->pc : pc,
+ .symbol = ksym_getstr(current) };
+
+ frame = (ptr_t*)*frame;
+ i++;
+ }
+
+ if (last_fp) {
+ *last_fp = (ptr_t)frame;
+ }
+
+ return i;
+}
+
+void
+trace_printstack_of(ptr_t fp)
+{
+ struct trace_record tbs[NB_TRACEBACK];
+
+ int n = trace_walkback(tbs, fp, NB_TRACEBACK, &fp);
+
+ if (fp) {
+ kprintf(KDEBUG "...<truncated>\n");
+ }
+
+ for (int i = 0; i < n; i++) {
+ kprintf(KDEBUG "%p: %s\n", tbs[i].pc, tbs[i].symbol);
+ }
+}
+
+void
+trace_printstack()
{
- return NULL;
+ trace_printstack_of(cpu_get_fp());
}
void
-trace_walkback(ptr_t fp)
+trace_printswctx(const isr_param* p, char* direction)
{
+
+ struct ksym_entry* sym = trace_sym_lookup(p->execp->eip);
+
+ kprintf(
+ KDEBUG ">> (sw:%s) iv:%d, errno:%p <<\n", direction, p->execp->vector);
+ kprintf(KDEBUG "%p:%s\n", p->execp->eip, ksym_getstr(sym));
+}
+
+void
+trace_printstack_isr(const isr_param* isrm)
+{
+ isr_param* p = isrm;
+ ptr_t fp = cpu_get_fp();
+ int prev_fromusr = uspace_context(p);
+
+ kprintf(KDEBUG "\n");
+ kprintf(KDEBUG "stack trace (pid=%d)\n", __current->pid);
+
+ trace_printstack_of(fp);
+
+ while (p) {
+ if (!prev_fromusr) {
+ if (uspace_context(p)) {
+ trace_printswctx(p, "s/u");
+ } else {
+ trace_printswctx(p, "s/s");
+ }
+ } else {
+ trace_printswctx(p, "u/s");
+ }
+
+ fp = saved_fp(p);
+ trace_printstack_of(fp);
+
+ prev_fromusr = uspace_context(p);
+
+ p = p->execp->saved_prev_ctx;
+ }
+ kprintf(KDEBUG "\n");
}
\ No newline at end of file
-#include <hal/cpu.h>
+#include <sys/cpu.h>
#include <klibc/string.h>
#include <lunaix/mm/pmm.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/syslog.h>
#include <lunaix/timer.h>
-#include <hal/cpu.h>
+#include <sys/cpu.h>
#include <hal/intc.h>
#include <klibc/string.h>
-#include <hal/cpu.h>
+#include <sys/cpu.h>
#include <lunaix/peripheral/serial.h>
#include <lunaix/syslog.h>
#include <sys/port_io.h>
#include <sys/interrupts.h>
#include <sys/mm/mempart.h>
-#include <hal/cpu.h>
+#include <sys/cpu.h>
#include <hal/intc.h>
#include <lunaix/fs/taskfs.h>
sym_line = re.compile(r"^(?P<addr>[0-9a-f]+)\s[a-z]\s+F\s+\.[a-z._]+\s+[0-9a-f]+(?P<label>.+)$")
-def main(kbin, sym_out, endianness='little', bits=32):
+def main(kbin, sym_out, endianness='little', bits=32, just_print=False):
assert bits >= 32
assert (1 << int(math.log2(bits))) == bits
functions.append((addr, label))
functions = sorted(functions, key=lambda x: x[0])
+
+ if just_print:
+ for (a, l) in functions:
+ print(hex(a), ":", l)
+ return
# struct {
# ptr_t addr;
parser.add_argument('-o', '--outfile', required=True)
parser.add_argument('--bits', default=32)
parser.add_argument('--order', default='little')
+ parser.add_argument('-p', '--just-print', action='store_true')
args = parser.parse_args()
- main(args.elf_exec, args.outfile, endianness=args.order, bits=int(args.bits))
+ main(args.elf_exec, args.outfile, endianness=args.order, bits=int(args.bits), just_print=args.just_print)
.section .text
.global _start
- _start:
+ _start:
xorl %eax, %eax
+ xorl %ebp, %ebp
fninit
call main