:: commit 3c790f988b88b510aacfcb6b164d1d38da257ff0

mintsuki <mintsuki@protonmail.com> — 2020-09-18 08:57

parents: 8271c0b8df

Clarify the stack situation in stivale specs

diff --git a/STIVALE.md b/STIVALE.md
index 661501aa..772a85f2 100644
--- a/STIVALE.md
+++ b/STIVALE.md
@@ -39,11 +39,11 @@ the value of `entry_point`.
 At entry, the bootloader will have setup paging mappings as such:
 
 ```
- Base Physical Address -                      Size                      ->  Virtual address
-  0x0000000000000000   -   4 GiB plus any additional memory map entry   ->  0x0000000000000000
-  0x0000000000000000   -   4 GiB plus any additional memory map entry   ->  0xffff800000000000 (4-level paging only)
-  0x0000000000000000   -   4 GiB plus any additional memory map entry   ->  0xff00000000000000 (5-level paging only)
-  0x0000000000000000   -                   0x80000000                   ->  0xffffffff80000000
+ Base Physical Address -                    Size                    ->  Virtual address
+  0x0000000000000000   - 4 GiB plus any additional memory map entry -> 0x0000000000000000
+  0x0000000000000000   - 4 GiB plus any additional memory map entry -> 0xffff800000000000 (4-level paging only)
+  0x0000000000000000   - 4 GiB plus any additional memory map entry -> 0xff00000000000000 (5-level paging only)
+  0x0000000000000000   -                 0x80000000                 -> 0xffffffff80000000
 ```
 
 If the kernel is dynamic and not statically linked, the bootloader will relocate it.
@@ -72,7 +72,9 @@ The A20 gate is enabled.
 
 PIC/APIC IRQs are all masked.
 
-`rsp` is set to the requested stack as per stivale header.
+`rsp` is set to the requested stack as per stivale header. If the requested value is
+non-null, an invalid return address of 0 is pushed to the stack before jumping
+to the kernel.
 
 `rdi` will point to the stivale structure (described below).
 
@@ -100,7 +102,8 @@ The A20 gate is enabled.
 
 PIC/APIC IRQs are all masked.
 
-`esp` is set to the requested stack as per stivale header.
+`esp` is set to the requested stack as per stivale header. An invalid return address
+of 0 is pushed to the stack before jumping to the kernel.
 
 A pointer to the stivale structure (described below) is pushed onto this stack
 before the entry point is called.
@@ -115,8 +118,12 @@ the header that the bootloader will parse.
 Said header looks like this:
 ```c
 struct stivale_header {
-    uint64_t stack;   // This is the stack address which will be in RSP
+    uint64_t stack;   // This is the stack address which will be in ESP/RSP
                       // when the kernel is loaded.
+                      // It can only be set to NULL for 64-bit kernels. 32-bit
+                      // kernels are mandated to provide a vaild stack.
+                      // 64-bit and 32-bit valid stacks must be at least 256 bytes
+                      // in usable space and must be 16 byte aligned addresses.
 
     uint16_t flags;   // Flags
                       // bit 0  0 = text mode, 1 = graphics framebuffer mode
diff --git a/STIVALE2.md b/STIVALE2.md
index 719257e4..8a7109f6 100644
--- a/STIVALE2.md
+++ b/STIVALE2.md
@@ -39,11 +39,11 @@ the value of `entry_point`.
 At entry, the bootloader will have setup paging mappings as such:
 
 ```
- Base Physical Address -                      Size                      ->  Virtual address
-  0x0000000000000000   -   4 GiB plus any additional memory map entry   ->  0x0000000000000000
-  0x0000000000000000   -   4 GiB plus any additional memory map entry   ->  0xffff800000000000 (4-level paging only)
-  0x0000000000000000   -   4 GiB plus any additional memory map entry   ->  0xff00000000000000 (5-level paging only)
-  0x0000000000000000   -                   0x80000000                   ->  0xffffffff80000000
+ Base Physical Address -                    Size                    ->  Virtual address
+  0x0000000000000000   - 4 GiB plus any additional memory map entry -> 0x0000000000000000
+  0x0000000000000000   - 4 GiB plus any additional memory map entry -> 0xffff800000000000 (4-level paging only)
+  0x0000000000000000   - 4 GiB plus any additional memory map entry -> 0xff00000000000000 (5-level paging only)
+  0x0000000000000000   -                 0x80000000                 -> 0xffffffff80000000
 ```
 
 If the kernel is dynamic and not statically linked, the bootloader will relocate it.
@@ -72,7 +72,9 @@ The A20 gate is enabled.
 
 PIC/APIC IRQs are all masked.
 
-`rsp` is set to the requested stack as per stivale2 header.
+`rsp` is set to the requested stack as per stivale2 header. If the requested value is
+non-null, an invalid return address of 0 is pushed to the stack before jumping
+to the kernel.
 
 `rdi` will point to the stivale2 structure (described below).
 
@@ -100,7 +102,8 @@ The A20 gate is enabled.
 
 PIC/APIC IRQs are all masked.
 
-`esp` is set to the requested stack as per stivale2 header.
+`esp` is set to the requested stack as per stivale2 header. An invalid return address
+of 0 is pushed to the stack before jumping to the kernel.
 
 A pointer to the stivale2 structure (described below) is pushed onto this stack
 before the entry point is called.
@@ -120,11 +123,12 @@ struct stivale2_header {
                             // If set to 0, the ELF entry point will be used
                             // instead.
 
-    uint64_t stack;         // This is the stack address which will be in RSP
+    uint64_t stack;         // This is the stack address which will be in ESP/RSP
                             // when the kernel is loaded.
-                            // It can be set to a non-valid stack address such as 0
-                            // as long as the OS is 64-bit and sets up a stack on its
-                            // own.
+                            // It can only be set to NULL for 64-bit kernels. 32-bit
+                            // kernels are mandated to provide a vaild stack.
+                            // 64-bit and 32-bit valid stacks must be at least 256 bytes
+                            // in usable space and must be 16 byte aligned addresses.
 
     uint64_t flags;         // Bit 0: if 1, enable KASLR
                             // All other bits undefined
diff --git a/limine.bin b/limine.bin
index 33c6707b..f3516ea4 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/protos/stivale.c b/stage2/protos/stivale.c
index 29ce4ceb..1303dd30 100644
--- a/stage2/protos/stivale.c
+++ b/stage2/protos/stivale.c
@@ -334,8 +334,17 @@ __attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg,
             "mov ebx, ebx\n\t"
             "mov edi, edi\n\t"
 
+            // Let's pretend we push a return address
+            "mov rsi, qword ptr [rsi]\n\t"
+            "test rsi, rsi\n\t"
+            "jz 1f\n\t"
+
+            "sub rsi, 8\n\t"
+            "mov qword ptr [rsi], 0\n\t"
+
+            "1:\n\t"
             "push 0x30\n\t"
-            "push [rsi]\n\t"
+            "push rsi\n\t"
             "pushfq\n\t"
             "push 0x28\n\t"
             "push [rbx]\n\t"
tab: 248 wrap: offon