]> Zhao Yanbai Git Server - kernel.git/commitdiff
实现系统调用返回随机数
authorzhaoyanbai <zhaoyanbai@126.com>
Sat, 15 Aug 2026 04:20:16 +0000 (12:20 +0800)
committerzhaoyanbai <zhaoyanbai@126.com>
Sat, 15 Aug 2026 04:20:21 +0000 (12:20 +0800)
include/cpuid.h
kernel/ring3.S
kernel/syscall.c
qemu.sh

index d7ceb499a23964a1c8357c3224ed8c5938e78765..aa67bfe1667ea58cbbedd62999b22ee78819a0a2 100644 (file)
@@ -9,6 +9,8 @@
 
 #pragma once
 
+#define CPUID_FEAT_ECX_RDRAND (1u << 30)
+
 typedef struct cpuid_regs {
     unsigned long eax, ebx, ecx, edx;
 } cpuid_regs_t;
index ba947bdb70fb6692b673a6be901a94001e066834..59662ef1628ece1e146c3ff6838d78736f5714cc 100644 (file)
@@ -27,6 +27,11 @@ ring3_entry:
     nop
     nop
 
+    pushl   $0                  # 模拟一个内核不需要的参数1
+    pushl   $SYSC_TEST
+    call    ring3_syscall
+    addl    $8, %esp
+
     pushl   $0                  # 模拟一个内核不需要的参数1
     pushl   $SYSC_RAND          # 系统调用号
     call    ring3_syscall
index 0dfb2ce13934fc66b1171596e04926dd3169dabd..3b217b00df68c1006f8332061042b379ac7d6894 100644 (file)
@@ -20,6 +20,7 @@
 #include "system.h"
 #include "timer.h"
 #include "clock.h"
+#include "cpuid.h"
 
 extern void syscall_entry();
 extern void init_sysc_handler_table();
@@ -76,6 +77,11 @@ int sysc_wait(int ticks) {
 }
 
 int sysc_test() {
+    // 测试修改优先级
+    int priority = current->priority;
+    priority += 1;
+    priority = TASK_PRIORITY_LEVEL_USER + (priority % 10);
+    task_reset_priority(priority);
     return 0;
 }
 int sysc_pause() {
@@ -89,7 +95,33 @@ int sysc_debug(unsigned int v) {
 }
 
 int sysc_rand() {
+    bool has_rdrand = false;
+    cpuid_regs_t cpuid_regs = cpuid(1);
+    if (cpuid_regs.ecx & CPUID_FEAT_ECX_RDRAND) {
+        has_rdrand = true;
+    }
+
     uint32_t rand = jiffies;
+    static uint32_t rand_seed = 0;
+
+    if (has_rdrand) {
+        asm volatile("rdrand %0" : "=r"(rand) : : "cc");
+    } else {
+        if (0 == rand_seed) {
+            rand_seed = jiffies;
+            int cnt = (jiffies % 32);
+            for (int i = 0; i < cnt; i++) {
+                uint32_t bit = rand_seed & 1;
+                rand_seed >>= 1;
+                rand_seed |= (bit << 31);
+            }
+            rand_seed ^= ((uint32_t)rdtsc());
+        }
+
+        rand_seed = rand_seed * 1664525u + 1013904223u;
+        rand = rand_seed;
+    }
+
     return (int)rand;
 }
 
diff --git a/qemu.sh b/qemu.sh
index b4bbf40c3bf58bc684af3be042a8db5786a3fe8c..6081937d04ca10445f9ee8ef130873e8d25d3f78 100755 (executable)
--- a/qemu.sh
+++ b/qemu.sh
@@ -21,7 +21,7 @@ qemu-system-i386 \
     -boot d \
     -m 128\
     -smp 2 \
-    -cpu qemu32,+x2apic \
+    -cpu qemu32,+x2apic,+rdrand \
     -machine q35 \
     -serial tcp::6666,server,nowait \
     -drive file=sata.img,format=raw,if=none,id=sata-disk \