sudharson14 / xv6-OS-for-arm-v8

OS support for 64 bit ARM architecture
42 stars 23 forks source link

cannot go into shell #2

Open figozhang opened 6 years ago

figozhang commented 6 years ago

i try your git tree on qemu, but it cannot go into shell, here is log:

starting xv6 for ARMv8... Implementer: ARM Limited Current EL: EL1 Flushing TLB and Instr Cache Setting Memory Attribute Indirection Register (MAIR_EL1) Setting Vector Base Address Register (VBAR_EL1) Setting Translation Control Register (TCR_EL1) Setting Translation Table Base Register 1 (TTBR1_EL1) Setting Translation Table Base Register 0 (TTBR0_EL1) Setting System Control Register (SCTLR_EL1) System Configure Completed...

clearing BSS section for the main kernel Starting Kernel

takeharukato commented 5 years ago

Hi,

I also meet same problem. As far as I investigated the issue, there are two problems at least. 1) Accessing EL3 register Certainly, some hardware like RASPI3 starts from EL3 or EL2. But in this case, bootloader or OS kernel should entering el1. So exception handler use el1 system registers however 6a17d accesses elr_el3 and spsr_el3. This cause sync trap repeatedly. This is a main cause of hung. 2) The change of trap frame layout should be applied to struct trapframe 6a17d changes trapframe, but struct trapframe has not been changed yet.

You can see the current snapshot of my work at https://github.com/takeharukato/xv6-OS-for-arm-v8/tree/devel-tkato-rework-aarch64-work .

I fixed these thing to confirm my investigation, but I got a message 'und at: 0xffffffff47fdbee01` In this case user instruction does not point regular address.

xv6 on ARMv8-A (64-bit) Architecture message banner is printed by init so this indicates the kernel could invoke init.

starting xv6 for ARMv8...
Implementer: ARM Limited
Current EL: EL1
Flushing TLB and Instr Cache
Setting Memory Attribute Indirection Register (MAIR_EL1)
Setting Vector Base Address Register (VBAR_EL1)
Setting Translation Control Register (TCR_EL1)
Setting Translation Table Base Register 1 (TTBR1_EL1)
Setting Translation Table Base Register 0 (TTBR0_EL1)
Setting System Control Register (SCTLR_EL1)
System Configure Completed...

clearing BSS section for the main kernel
Starting Kernel

**************************************************************************
**                                                                      **
**                                                                      **
**                  xv6 on ARMv8-A (64-bit) Architecture                **
**                                                                      **
**                                                                      **
***********************Gund at: 0xffffffff47fdbee0
     sp: 0x3ed8
     pc: 0xffffffff47fdbee0
   spsr: 0x20000000
     r0: 0x1
     r1: 0x1
     r2: 0x3ed3
     r3: 0x1
     r4: 0xffffffff47fdbed0
     r5: 0x0
     r6: 0x0
     r7: 0x0
     r8: 0x0
     r9: 0x0
    r10: 0x0
    r11: 0x0
    r12: 0x0
    r13: 0x0
    r14: 0x0
    r15: 0x0
    r16: 0x0
    r17: 0x0
    r18: 0x0
    r19: 0x0
    r20: 0x0
    r21: 0x0
    r22: 0x0
    r23: 0x0
    r24: 0x0
    r25: 0x0
    r26: 0x0
    r27: 0x0
    r28: 0x0
    r29: 0x3c040035874
    r30: 0xffffffff47fdbee0

I hope that this might be useful information for you.

Thanks, Regards,

takeharukato commented 5 years ago

Hi,

After all, I found the cause of this hang and I fixed this problem, may be.

I've done the following things and the kernel work fine again.

(1) Fix the definition of struct trapframe to adapt to the current trap frame in trap_asm.S (2) Use elr_el1, spsr_el1 instead of elr_el3, spsr_el3 because EL3 is used by security monitors not OS kernels. (3) Set a kernel stack pointer ( sp ) to the bottom of process's kernel stack when the kernel returns to EL0.

I've pushed my fix to https://github.com/takeharukato/xv6-OS-for-arm-v8/tree/devel-tkato-rework-aarch64-work . Would you please give it a try?

FYI, I show the result of my fix:

$ ./run.sh
starting xv6 for ARMv8...
Implementer: ARM Limited
Current EL: EL1
Flushing TLB and Instr Cache
Setting Memory Attribute Indirection Register (MAIR_EL1)
Setting Vector Base Address Register (VBAR_EL1)
Setting Translation Control Register (TCR_EL1)
Setting Translation Table Base Register 1 (TTBR1_EL1)
Setting Translation Table Base Register 0 (TTBR0_EL1)
Setting System Control Register (SCTLR_EL1)
System Configure Completed...

clearing BSS section for the main kernel
Starting Kernel

**************************************************************************
**                                                                      **
**                                                                      **
**                  xv6 on ARMv8-A (64-bit) Architecture                **
**                                                                      **
**                                                                      **
**************************************************************************

init: Starting Shell
$

I show what I modified as follows:

diff --git a/xv6-armv8/arm.h b/xv6-armv8/arm.h
index 94fcf02..fb0dd06 100644
--- a/xv6-armv8/arm.h
+++ b/xv6-armv8/arm.h
@@ -21,9 +21,6 @@
 // and switches to a new process (including user-space banked registers)
 #ifndef __ASSEMBLER__
 struct trapframe {
-    uint64    sp;     // user mode sp
-    uint64    pc;     // user mode pc (elr)
-    uint64    spsr;
     uint64    r0;
     uint64    r1;
     uint64    r2;
@@ -55,6 +52,9 @@ struct trapframe {
     uint64    r28;
     uint64    r29;
     uint64    r30;     // user mode lr
+    uint64    sp;     // user mode sp
+    uint64    pc;     // user mode pc (elr)
+    uint64    spsr;
 };
 #endif

diff --git a/xv6-armv8/trap_asm.S b/xv6-armv8/trap_asm.S
index 04227f4..d364676 100644
--- a/xv6-armv8/trap_asm.S
+++ b/xv6-armv8/trap_asm.S
@@ -20,8 +20,8 @@
        stp     x0, x1, [sp, #-16]!
        add x21, sp, #0x110

-       mrs     x22, elr_el3             /* ELR */
-       mrs     x23, spsr_el3            /* SPSR */
+       mrs     x22, elr_el1             /* ELR */
+       mrs     x23, spsr_el1            /* SPSR */

        stp     x30, x21, [sp, #0xf0]    /* LR, SP */
        stp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
@@ -31,8 +31,8 @@
        ldp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
        ldp     x30, x28, [sp, #0xf0]    /* LR, SP */

-       msr     elr_el3, x22             /* ELR */
-       msr     spsr_el3, x23
+       msr     elr_el1, x22             /* ELR */
+       msr     spsr_el1, x23

        mov x29, sp
        mov sp, x28
@@ -75,8 +75,8 @@
        stp     x0, x1, [sp, #-16]!

        mrs x21, sp_el0
-       mrs     x22, elr_el3             /* ELR */
-       mrs     x23, spsr_el3            /* SPSR */
+       mrs     x22, elr_el1             /* ELR */
+       mrs     x23, spsr_el1            /* SPSR */

        stp     x30, x21, [sp, #0xf0]    /* LR, SP */
        stp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
@@ -86,11 +86,12 @@
        ldp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
        ldp     x30, x28, [sp, #0xf0]    /* LR, SP */

-       msr     elr_el3, x22             /* ELR */
-       msr     spsr_el3, x23
+       msr     elr_el1, x22             /* ELR */
+       msr     spsr_el1, x23
        msr sp_el0, x28

        mov x29, sp
+       add sp, sp, #0x110

        ldp     x0, x1, [x29], #16
        ldp     x2, x3, [x29], #16

I might have written the codes to move into EL1 from EL2/EL3 before I sent a PR. But I can not write and test such codes because I do not have a machine which boots the kernel from EL3.

Thanks, Regards,

hyperswine commented 10 months ago

Hi,

After all, I found the cause of this hang and I fixed this problem, may be.

I've done the following things and the kernel work fine again.

(1) Fix the definition of struct trapframe to adapt to the current trap frame in trap_asm.S (2) Use elr_el1, spsr_el1 instead of elr_el3, spsr_el3 because EL3 is used by security monitors not OS kernels. (3) Set a kernel stack pointer ( sp ) to the bottom of process's kernel stack when the kernel returns to EL0.

I've pushed my fix to https://github.com/takeharukato/xv6-OS-for-arm-v8/tree/devel-tkato-rework-aarch64-work . Would you please give it a try?

FYI, I show the result of my fix:

$ ./run.sh
starting xv6 for ARMv8...
Implementer: ARM Limited
Current EL: EL1
Flushing TLB and Instr Cache
Setting Memory Attribute Indirection Register (MAIR_EL1)
Setting Vector Base Address Register (VBAR_EL1)
Setting Translation Control Register (TCR_EL1)
Setting Translation Table Base Register 1 (TTBR1_EL1)
Setting Translation Table Base Register 0 (TTBR0_EL1)
Setting System Control Register (SCTLR_EL1)
System Configure Completed...

clearing BSS section for the main kernel
Starting Kernel

**************************************************************************
**                                                                      **
**                                                                      **
**                  xv6 on ARMv8-A (64-bit) Architecture                **
**                                                                      **
**                                                                      **
**************************************************************************

init: Starting Shell
$

I show what I modified as follows:

diff --git a/xv6-armv8/arm.h b/xv6-armv8/arm.h
index 94fcf02..fb0dd06 100644
--- a/xv6-armv8/arm.h
+++ b/xv6-armv8/arm.h
@@ -21,9 +21,6 @@
 // and switches to a new process (including user-space banked registers)
 #ifndef __ASSEMBLER__
 struct trapframe {
-    uint64    sp;     // user mode sp
-    uint64    pc;     // user mode pc (elr)
-    uint64    spsr;
     uint64    r0;
     uint64    r1;
     uint64    r2;
@@ -55,6 +52,9 @@ struct trapframe {
     uint64    r28;
     uint64    r29;
     uint64    r30;     // user mode lr
+    uint64    sp;     // user mode sp
+    uint64    pc;     // user mode pc (elr)
+    uint64    spsr;
 };
 #endif

diff --git a/xv6-armv8/trap_asm.S b/xv6-armv8/trap_asm.S
index 04227f4..d364676 100644
--- a/xv6-armv8/trap_asm.S
+++ b/xv6-armv8/trap_asm.S
@@ -20,8 +20,8 @@
        stp     x0, x1, [sp, #-16]!
        add x21, sp, #0x110

-       mrs     x22, elr_el3             /* ELR */
-       mrs     x23, spsr_el3            /* SPSR */
+       mrs     x22, elr_el1             /* ELR */
+       mrs     x23, spsr_el1            /* SPSR */

        stp     x30, x21, [sp, #0xf0]    /* LR, SP */
        stp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
@@ -31,8 +31,8 @@
        ldp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
        ldp     x30, x28, [sp, #0xf0]    /* LR, SP */

-       msr     elr_el3, x22             /* ELR */
-       msr     spsr_el3, x23
+       msr     elr_el1, x22             /* ELR */
+       msr     spsr_el1, x23

        mov x29, sp
        mov sp, x28
@@ -75,8 +75,8 @@
        stp     x0, x1, [sp, #-16]!

        mrs x21, sp_el0
-       mrs     x22, elr_el3             /* ELR */
-       mrs     x23, spsr_el3            /* SPSR */
+       mrs     x22, elr_el1             /* ELR */
+       mrs     x23, spsr_el1            /* SPSR */

        stp     x30, x21, [sp, #0xf0]    /* LR, SP */
        stp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
@@ -86,11 +86,12 @@
        ldp     x22, x23, [sp, #0x100]   /* ELR, SPSR */
        ldp     x30, x28, [sp, #0xf0]    /* LR, SP */

-       msr     elr_el3, x22             /* ELR */
-       msr     spsr_el3, x23
+       msr     elr_el1, x22             /* ELR */
+       msr     spsr_el1, x23
        msr sp_el0, x28

        mov x29, sp
+       add sp, sp, #0x110

        ldp     x0, x1, [x29], #16
        ldp     x2, x3, [x29], #16

I might have written the codes to move into EL1 from EL2/EL3 before I sent a PR. But I can not write and test such codes because I do not have a machine which boots the kernel from EL3.

Thanks, Regards,

that seems like a useful fix. But doesnt work for me on m2 macos, still stuck in the same issue, any ideas?