diff --git a/bsp/qemu-vexpress-a9/applications/mnt.c b/bsp/qemu-vexpress-a9/applications/mnt.c index bb5c977e8848c4b7c69a1196fd709cc31564abde..0fc9b62860b9a1d6090c433bed5a5c7873844649 100644 --- a/bsp/qemu-vexpress-a9/applications/mnt.c +++ b/bsp/qemu-vexpress-a9/applications/mnt.c @@ -13,7 +13,7 @@ int mnt_init(void) } rt_thread_mdelay(200); - if (dfs_mount("sd0", "/mnt", "elm", 0, NULL) != 0) + if (dfs_mount("sd", "/mnt", "elm", 0, NULL) != 0) { rt_kprintf("Dir /mnt mount failed!\n"); return -1; diff --git a/bsp/x86/drivers/board.c b/bsp/x86/drivers/board.c index 07400033c06cb8ceb02fe0d9328efeb2a7cfbac4..6f898d83e9c794f513d70a807691d991d020c034 100644 --- a/bsp/x86/drivers/board.c +++ b/bsp/x86/drivers/board.c @@ -67,7 +67,8 @@ void rt_hw_board_init(void) init_page_region.start = (size_t)HW_PAGE_START; init_page_region.end = page_region_init(); /* init no mapped area in kernel table, must in kernel space */ - RT_ASSERT(!rt_hw_mmu_map_init(&mmu_info, (void *)HW_KERNEL_DELAY_MAP_START, HW_KERNEL_DELAY_MAP_SIZE, (rt_size_t *)g_mmu_table, 0)) + RT_ASSERT(!rt_hw_mmu_map_init(&mmu_info, (void *)HW_KERNEL_DELAY_MAP_START, + HW_KERNEL_DELAY_MAP_SIZE, (rt_size_t *)g_mmu_table, 0)) rt_page_init(init_page_region); /* map kernel space, then can read/write this area directly. */ diff --git a/bsp/x86/drivers/drv_uart.c b/bsp/x86/drivers/drv_uart.c index 6c1c0063b8ae4a8c834daeb643b8793422e05c87..39f542fbfcb7c7239e4937587060dc9cdf0910f5 100644 --- a/bsp/x86/drivers/drv_uart.c +++ b/bsp/x86/drivers/drv_uart.c @@ -41,8 +41,8 @@ struct hw_uart_device #define SERIAL0_IRQ 4 #define SERIAL1_IRQ 3 -#define MAX_BAUD_VALUE 11520 -#define DEFAULT_BAUD_VALUE 11520 +#define MAX_BAUD_VALUE 115200 +#define DEFAULT_BAUD_VALUE 115200 #define DEFAULT_DIVISOR_VALUE (MAX_BAUD_VALUE / DEFAULT_BAUD_VALUE) enum uart_fifo_control_register_bits @@ -281,7 +281,7 @@ static void do_uart_init(char *name, struct hw_uart_device *uart, struct rt_seri /* register device */ rt_hw_serial_register(serial, name, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, uart); rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, name); rt_hw_interrupt_umask(uart->irqno); diff --git a/bsp/x86/rtconfig.py b/bsp/x86/rtconfig.py index 49fbcffc90a9a5ea113a2f2f5e73d7b3cfb09339..3cd87e822bff8a462360d99bb7271834bfa1c07f 100644 --- a/bsp/x86/rtconfig.py +++ b/bsp/x86/rtconfig.py @@ -31,23 +31,37 @@ if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') BUILD = 'debug' +LIBC_MODE = 'release' # 'debug' or 'release', if debug, use libc in components, or not use libc with toolchain if PLATFORM == 'gcc': # toolchains PREFIX = 'i386-unknown-linux-musl-' - CC = PREFIX + 'gcc -fno-builtin -fno-stack-protector -nostdinc -nostdlib' - AS = PREFIX + 'gcc -nostdinc -nostdlib' + + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' AR = PREFIX + 'ar' - LINK = PREFIX + 'ld' + LINK = PREFIX + 'gcc' TARGET_EXT = 'elf' SIZE = PREFIX + 'size' OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' DEVICE = '' - CFLAGS = DEVICE + ' -Wall' + + if LIBC_MODE == 'debug': + EXT_CFLAGS = ' -nostdinc -nostdlib -fno-builtin -fno-stack-protector' + else: + EXT_CFLAGS = '' + + CFLAGS = DEVICE + ' -Wall' + EXT_CFLAGS AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' - LFLAGS = DEVICE + ' -Map rtthread-i386.map -nostdlib -n -T link.lds' + + if LIBC_MODE == 'debug': + EXT_LFLAGS = ' -nostdlib' + else: + EXT_LFLAGS = '' + + LFLAGS = DEVICE + ' -static -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref -n -T link.lds' + EXT_LFLAGS CPATH = '' LPATH = '' diff --git a/components/lwp/arch/x86/i386/lwp_arch.c b/components/lwp/arch/x86/i386/lwp_arch.c index c4a78b8ed2d89bd8b255b859bdac5ec687381d89..568205955913fce1d6fb27b0a1207e5f4f749ba8 100644 --- a/components/lwp/arch/x86/i386/lwp_arch.c +++ b/components/lwp/arch/x86/i386/lwp_arch.c @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef RT_USING_USERSPACE @@ -23,7 +24,10 @@ #include #include #include + +#ifdef RT_USING_SIGNALS #include +#endif /* RT_USING_SIGNALS */ extern size_t g_mmu_table[]; @@ -39,8 +43,24 @@ int arch_expand_user_stack(void *addr) if (map || lwp_user_accessable(addr, 1)) { - ret = 1; + ret = 1; /* map success */ } + else /* map failed, send signal SIGSEGV */ + { +#ifdef RT_USING_SIGNALS + dbg_log(DBG_ERROR, "[fault] thread %s mapped addr %p failed!\n", rt_thread_self()->name, addr); + lwp_thread_kill(rt_thread_self(), SIGSEGV); + ret = 1; /* return 1, will return back to intr, then check exit */ +#endif + } + } + else /* not stack, send signal SIGSEGV */ + { +#ifdef RT_USING_SIGNALS + dbg_log(DBG_ERROR, "[fault] thread %s access unmapped addr %p!\n", rt_thread_self()->name, addr); + lwp_thread_kill(rt_thread_self(), SIGSEGV); + ret = 1; /* return 1, will return back to intr, then check exit */ +#endif } return ret; } diff --git a/libcpu/x86/i386/interrupt.c b/libcpu/x86/i386/interrupt.c index 0348e30b0b3da3dcb7f8ca6404b86e4d492e8d53..f499d217da1057dc51af739fe2cd7757bd126629 100644 --- a/libcpu/x86/i386/interrupt.c +++ b/libcpu/x86/i386/interrupt.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,35 @@ #include #include +#ifdef RT_USING_SIGNALS +#include +#endif /* RT_USING_SIGNALS */ + +enum HW_EXCEPTION_TYPE +{ + HW_EXCEPT_DIVIDE = 0, /* Division error: DIV and IDIV instructions */ + HW_EXCEPT_DEBUG, /* Debugging exceptions: access to any code and data */ + HW_EXCEPT_INTERRUPT, /* Unshielded interrupt: Unshielded external interrupt */ + HW_EXCEPT_BREAKPOINT, /* Debug breakpoint: instruction INT3 */ + HW_EXCEPT_OVERFLOW, /* Overflow: instruction INTO */ + HW_EXCEPT_BOUND_RANGE, /* Out of bounds: command BOUND */ + HW_EXCEPT_INVALID_OPCODE, /* Invalid (undefined) opcode: instruction UD2 or invalid instruction */ + HW_EXCEPT_DEVICE_NOT_AVAILABLE, /* Device unavailable (no math processor): floating point or WAIT/FWAIT instructions */ + HW_EXCEPT_DOUBLE_FAULT, /* Double error: all instructions that can generate an exception or NMI or INTR */ + HW_EXCEPT_COPROCESSOR_SEGMENT_OVERRUN, /* Assist the processor segment to cross the boundary: floating-point instructions + (IA32 processors after 386 no longer generate such exceptions) */ + HW_EXCEPT_INVALID_TSS, /* Invalid TSS: When switching tasks or accessing TSS */ + HW_EXCEPT_SEGMENT_NOT_PRESENT, /* Segment does not exist: when loading segment registers or accessing system segments */ + HW_EXCEPT_STACK_FAULT, /* Stack segmentation error: stack operation or loading SS */ + HW_EXCEPT_GENERAL_PROTECTION, /* General protection error: memory or other protection check */ + HW_EXCEPT_PAGE_FAULT, /* Page fault: memory access */ + HW_EXCEPT_RESERVED, /* INTEL reserved, not used */ + HW_EXCEPT_X87_FLOAT_POINT, /* X87FPU floating point error (math error): X87FPU floating point instruction or WAIT/FWAIIT instruction */ + HW_EXCEPT_ALIGNMENT_CHECK, /* Alignment check: data access in memory (supported from 486) */ + HW_EXCEPT_MACHINE_CHECK, /* Machine Check: The error code (if any) and source depend on the specific mode (Pentium CPU starts to support) */ + HW_EXCEPT_SIMD_FLOAT_POINT, /* SIMD floating-point exceptions: SSE and SSE2 floating-point instructions (supported by Pentium III) */ +}; + typedef void (*rt_hw_intr_handler_t)(rt_hw_stack_frame_t *); static rt_hw_intr_handler_t interrupt_handlers[MAX_INTR_NR] = {0}; @@ -71,7 +101,6 @@ static void hw_external_handler(rt_hw_stack_frame_t *frame) rt_hw_pic_ack(irqno); } - #ifdef RT_USING_LWP static int check_user_stack(rt_hw_stack_frame_t *frame) { @@ -109,6 +138,53 @@ static void hw_exception_handler(rt_hw_stack_frame_t *frame) exception_frame_dump(frame); rt_hw_print_backtrace(); + +#ifdef RT_USING_SIGNALS + dbg_log(DBG_ERROR, "[exception] send signal to thread %s\n", rt_thread_self()->name); + /* send signal to thread */ + switch (frame->vec_no) + { + case HW_EXCEPT_DIVIDE: + case HW_EXCEPT_INVALID_OPCODE: + lwp_thread_kill(rt_thread_self(), SIGILL); + return; + case HW_EXCEPT_DEVICE_NOT_AVAILABLE: + lwp_thread_kill(rt_thread_self(), SIGIO); + return; + case HW_EXCEPT_COPROCESSOR_SEGMENT_OVERRUN: + case HW_EXCEPT_X87_FLOAT_POINT: + case HW_EXCEPT_SIMD_FLOAT_POINT: + lwp_thread_kill(rt_thread_self(), SIGFPE); + return; + case HW_EXCEPT_OVERFLOW: + case HW_EXCEPT_BOUND_RANGE: + case HW_EXCEPT_INVALID_TSS: + case HW_EXCEPT_ALIGNMENT_CHECK: + lwp_thread_kill(rt_thread_self(), SIGBUS); + return; + case HW_EXCEPT_SEGMENT_NOT_PRESENT: + case HW_EXCEPT_GENERAL_PROTECTION: + lwp_thread_kill(rt_thread_self(), SIGSEGV); + return; + case HW_EXCEPT_STACK_FAULT: + lwp_thread_kill(rt_thread_self(), SIGSTKFLT); + return; + case HW_EXCEPT_MACHINE_CHECK: + case HW_EXCEPT_INTERRUPT: + lwp_thread_kill(rt_thread_self(), SIGINT); + return; + case HW_EXCEPT_DOUBLE_FAULT: + lwp_thread_kill(rt_thread_self(), SIGKILL); + return; + case HW_EXCEPT_DEBUG: + case HW_EXCEPT_BREAKPOINT: + lwp_thread_kill(rt_thread_self(), SIGTRAP); + return; + default: + break; + } +#endif + /* unhandled exception */ rt_hw_interrupt_disable(); for (;;) @@ -140,19 +216,17 @@ void rt_hw_interrupt_dispatch(rt_hw_stack_frame_t *frame) void rt_hw_stack_frame_dump(rt_hw_stack_frame_t *frame) { - rt_kprintf("====stack frame dump====\n"); - rt_kprintf("edi:%x esi:%x ebp:%x esp dummy:%x ebx:%x edx:%x ecx:%x eax:%x\n", + rt_kprintf("edi:%x\nesi:%x\nebp:%x\nesp dummy:%x\nebx:%x\nedx:%x\necx:%x\neax:%x\n", frame->edi, frame->esi, frame->ebp, frame->esp_dummy, frame->ebx, frame->edx, frame->ecx, frame->eax); - rt_kprintf("gs:%x fs:%x es:%x ds:%x error code:%x eip:%x cs:%x eflags:%x esp:%x ss:%x\n", + rt_kprintf("gs:%x\nfs:%x\nes:%x\nds:%x\nerror code:%x\neip:%x\ncs:%x\neflags:%x\nesp:%x\nss:%x\n", frame->gs, frame->fs, frame->es, frame->ds, frame->error_code, frame->eip, frame->cs, frame->eflags, frame->esp, frame->ss); } static void exception_frame_dump(rt_hw_stack_frame_t *frame) { - rt_kprintf("====exception frame dump====\n"); - rt_kprintf("Stack frame: exception name %s\n", hw_exception_names[frame->vec_no]); + rt_kprintf("\n!!! Stack frame: exception name %s\n", hw_exception_names[frame->vec_no]); if (frame->vec_no == 14) { rt_kprintf("page fault addr: %p\n", read_cr2()); diff --git a/libcpu/x86/i386/syscall_c.c b/libcpu/x86/i386/syscall_c.c index db8767d1c01d9fb1375b845be9c2523fe5aa67eb..65c33bae3b669ab867e28d41deb6490d0671dc9b 100644 --- a/libcpu/x86/i386/syscall_c.c +++ b/libcpu/x86/i386/syscall_c.c @@ -11,6 +11,7 @@ #include #include +#include //#define DBG_LEVEL DBG_WARNING //#define DBG_LEVEL DBG_INFO @@ -27,6 +28,10 @@ #include "stackframe.h" +#ifdef RT_USING_SIGNALS +#include +#endif /* RT_USING_SIGNALS */ + typedef rt_size_t (*syscallfunc_t)(rt_size_t,rt_size_t,rt_size_t,rt_size_t,rt_size_t,rt_size_t,rt_size_t); syscallfunc_t lwp_get_sys_api(uint32_t); @@ -34,14 +39,22 @@ void rt_hw_syscall_dispath(struct rt_hw_stack_frame *frame) { if(frame->eax == 0) { - rt_kprintf("syscall id = 0!\n"); - while(1); // TODO: raise signal + dbg_log(DBG_ERROR, "[syscall] thread %s called syscall id = 0!\n", rt_thread_self()->name); +#ifdef RT_USING_SIGNALS + lwp_thread_kill(rt_thread_self(), SIGSYS); +#else + while(1); +#endif } if(frame->eax == 0xdeadbeef) { - rt_kprintf("syscall id = 0xdeadbeef\n"); - while(1); // TODO: raise signal + dbg_log(DBG_ERROR, "[syscall] thread %s called syscall id = 0xdeadbeef!\n", rt_thread_self()->name); +#ifdef RT_USING_SIGNALS + lwp_thread_kill(rt_thread_self(), SIGSYS); +#else + while(1); +#endif } #ifdef RT_USING_SIGNALS @@ -56,8 +69,12 @@ void rt_hw_syscall_dispath(struct rt_hw_stack_frame *frame) if(syscallfunc == RT_NULL) { - rt_kprintf("unsupported syscall %d!\n", frame->eax); - while(1); // TODO: raise signal + dbg_log(DBG_ERROR, "[syscall] thread %s called unsupported syscall %d!\n", rt_thread_self()->name, frame->eax); +#ifdef RT_USING_SIGNALS + lwp_thread_kill(rt_thread_self(), SIGSYS); +#else + while(1); +#endif } /* TODO: support arg6 */ LOG_I("\033[36msyscall id = %d,arg0 = 0x%p,arg1 = 0x%p,arg2 = 0x%p,arg3 = 0x%p,arg4 = 0x%p,arg5 = 0x%p,arg6 = 0x%p(unsupport)\n\033[37m",