diff --git a/docs/static/kalloc.jpg b/docs/static/kalloc.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c32fc4ac5f21522117b747c3ba0f126cce4fb98a
Binary files /dev/null and b/docs/static/kalloc.jpg differ
diff --git "a/docs/\351\241\271\347\233\256\350\256\276\350\256\241\346\226\207\346\241\243.md" "b/docs/\351\241\271\347\233\256\350\256\276\350\256\241\346\226\207\346\241\243.md"
index 85e06c9aac09952f934d3ac67e2e1d0ae99d623f..2e701686d93d86ee1a69950cac8a7ccc464bdca9 100644
--- "a/docs/\351\241\271\347\233\256\350\256\276\350\256\241\346\226\207\346\241\243.md"
+++ "b/docs/\351\241\271\347\233\256\350\256\276\350\256\241\346\226\207\346\241\243.md"
@@ -102,6 +102,8 @@ impl<T> Drop for SpinlockGuard<'_, T>{
 
 ```
 
+**睡眠锁**
+
 睡眠锁同自旋锁不同,自旋锁通过 CAS (Compare And Swap)来实现,而睡眠锁则除了使用自旋锁来保护睡眠锁之外,同时需要调用当前进程的 `sleep` 使其休眠并进入调度器进行调度,当调用之后则释放自旋锁。使用自旋锁来保护的原因是我们可以确保我们将不会错过任何一次 `wake_up` 来唤醒被休眠的进程。当睡眠锁解锁的时候,也需要去获取自旋锁并调用 `wake_up` 方法来唤醒被休眠的进程,之后释放自旋锁。
 
 **2. 静态变量**
@@ -293,6 +295,8 @@ pub struct ProcExtern {
 
     由于 rust 有 `alloc` 特性,提供了内存分配的 API。在提供了标准库的程序里都会有一个全局的内存分配器来进行内存分配,而在 `no_std` 的环境下,只要我们实现了 `alloc` 特性并提供了全局的内存分配器,我们就可以使用 `Box` 或者 `Vec` 等智能指针。而在我们的实现中,在**内核态**和**用户态**分别使用了不同的方法来实现。
 
+    ![](static/kalloc.jpg)
+
     **内核态**
 
     在内核态中,我们使用**伙伴内存分配系统**来实现。伙伴内存分配系统主要是为了减少内存的浪费,例如要分配一块大的内存,使用传统的链式内存分配只能寻找一块足够大的内存来分配,这时中间有很多小块的内存会被忽略,这时就会造成内存的浪费。
@@ -313,6 +317,10 @@ pub struct ProcExtern {
 
     当用户程序释放内存时,我们根据 Layout 的信息获取其指针和大小。当改内存块仍然在链表中则移动头部指针位置修改头部信息。若该内存块已经被移出链表,我们可以根据对应的头部信息将其重新加到链表对应的位置中。
 
+- 栈的改进
+
+    由于在 `xv6-riscv` 中的内核栈的大小为 4KB(即1页)。但4KB的大小对于某些进程来说是不够的,因此我们统一将每个进程的栈大小设置为 16KB(即4页)。当我们为每个进程映射栈内存时,需要分配5页,其中4页用来进行栈内存的映射,而最后一页则不进行映射,对于内核进行保护,当进程爆栈后会由于访问被保护的页而被强行终止而不会造成安全漏洞。0
+
 ### 三、实现描述
 
 请见该目录下其他文档,除此之外,我们也在代码中提供了详细的注释。由于时间原因,文档内容有空缺或者未更新,请见谅!