Bladeren bron

bitmap 功能函数

simon 1 jaar geleden
bovenliggende
commit
7f76d58970
5 gewijzigde bestanden met toevoegingen van 113 en 4 verwijderingen
  1. 1 3
      kernel/global.h
  2. 80 0
      lib/kernel/bitmap.c
  3. 21 0
      lib/kernel/bitmap.h
  4. 6 0
      lib/stdint.h
  5. 5 1
      makefile

+ 1 - 3
kernel/global.h

@@ -1,6 +1,6 @@
 #ifndef __KERNEL_GLOBAL_H
 #define __KERNEL_GLOBAL_H
-#include "stdint.h"
+#include "../lib/stdint.h"
 
 #define RPL0 0
 #define RPL1 1
@@ -27,6 +27,4 @@
 #define IDT_DESC_ATTR_DPL0 ((IDT_DESC_P << 7) + (IDT_DESC_DPL0 << 5) + IDT_DESC_32_TYPE)
 #define IDT_DESC_ATTR_DPL3 ((IDT_DESC_P << 7) + (IDT_DESC_DPL3 << 5) + IDT_DESC_32_TYPE)
 
-#define NULL ((void *)0)
-
 #endif // __KERNEL_GLOBAL_H

+ 80 - 0
lib/kernel/bitmap.c

@@ -0,0 +1,80 @@
+#include "bitmap.h"
+#include "../string.h"
+#include "../../kernel/debug.h"
+
+void bitmap_init(Bitmap *pb)
+{
+    _memset(pb->bits, 0, pb->btmp_bytes_len);
+}
+bool bitmap_scan_test(Bitmap *pb, uint32_t bit_idx)
+{
+    // 判断位图中 bit_idx 位是否为 1
+    uint32_t byte_idx = bit_idx / 8; // 向下取整用于索引数组下标
+    uint32_t bit_odd = bit_idx % 8;  // 取余用于索引数组内的位
+    return (pb->bits[byte_idx] & (BITMAP_MASK << bit_odd));
+}
+// 在位图中申请连续 cnt 个位,成功则返回起始位下标,失败返回-1
+int bitmap_scan(Bitmap *pb, uint32_t cnt)
+{
+    uint32_t idx_byte = 0; // 用于记录空闲位所在的字节
+    while ((0xff == pb->bits[idx_byte]) && (idx_byte < pb->btmp_bytes_len))
+    { // 如果字节为 0xff,表示该字节已经被占用,继续向下一个字节查找
+        idx_byte++;
+    }
+    ASSERT(idx_byte < pb->btmp_bytes_len);
+    if (idx_byte == pb->btmp_bytes_len)
+    { // 该内存池找不到可用空间
+        return -1;
+    }
+
+    // 若在位图数组范围内的某字节内找到了空闲位,则在字节内逐位查找空闲位的索引
+    int idx_bit = 0;
+    // 和 pb->bits[idx_byte] 这个字节逐位对比
+    while ((uint8_t)(BITMAP_MASK << idx_bit) & pb->bits[idx_byte])
+    { // 1 << idx_bit 生成 00010000 这样的数,和 pb->bits[idx_byte]逐位与操作
+        idx_bit++;
+    }
+    int bit_idx_start = idx_byte * 8 + idx_bit; // 空闲位在位图内的下标
+    if (cnt == 1)
+    {
+        return bit_idx_start;
+    }
+    uint32_t bit_left = (pb->btmp_bytes_len * 8 - bit_idx_start); // 记录还有多少位可以判断
+    uint32_t next_bit = bit_idx_start + 1;
+    uint32_t count = 1; // 用于记录找到的空闲位的个数
+
+    bit_idx_start = -1; // 先将其置为-1,若找不到连续的位就直接返回
+    while (bit_left-- > 0)
+    {
+        if (!(bitmap_scan_test(pb, next_bit)))
+        { // 若 next_bit 为 0
+            count++;
+        }
+        else
+        {
+            count = 0;
+        }
+        if (count == cnt)
+        { // 若找到连续的 cnt 个空闲位
+            bit_idx_start = next_bit - cnt + 1;
+            break;
+        }
+        next_bit++;
+    }
+    return bit_idx_start;
+}
+void bitmap_set(Bitmap *pb, uint32_t bit_idx, int8_t value)
+{
+    ASSERT((value == 0) || (value == 1));
+    uint32_t byte_idx = bit_idx / 8; // 向下取整用于索引数组下标
+    uint32_t bit_odd = bit_idx % 8;  // 取余用于索引数组内的位
+
+    if (value)
+    { // 若 value 为 1, 则 OR 1 到 bitmap[byte_idx] 的 bit_odd 位上
+        pb->bits[byte_idx] |= (BITMAP_MASK << bit_odd);
+    }
+    else
+    { // 若 value 为 0, 则 AND 0 到 bitmap[byte_idx] 的 bit_odd 位上
+        pb->bits[byte_idx] &= ~(BITMAP_MASK << bit_odd);
+    }
+}

+ 21 - 0
lib/kernel/bitmap.h

@@ -0,0 +1,21 @@
+#ifndef __LIB_KERNEL_BITMAP_H
+#define __LIB_KERNEL_BITMAP_H
+#include "../../kernel/global.h"
+
+#define BITMAP_MASK 1
+typedef struct
+{
+    uint32_t btmp_bytes_len; // 位图字节长度
+    uint8_t *bits;           // 位图的指针
+} __attribute__((packed)) Bitmap;
+
+// 初始化位图
+void bitmap_init(Bitmap *pb);
+// 判断位图中bit_idx位是否为1
+bool bitmap_scan_test(Bitmap *pb, uint32_t bit_idx);
+// 在位图中申请连续cnt个位,成功则返回起始位下标,失败返回-1
+int bitmap_scan(Bitmap *pb, uint32_t cnt);
+// 将位图pb的bit_idx位设置为value
+void bitmap_set(Bitmap *pb, uint32_t bit_idx, int8_t value);
+
+#endif // __LIB_KERNEL_BITMAP_H

+ 6 - 0
lib/stdint.h

@@ -1,6 +1,10 @@
 #ifndef __LIB_STDINT_H
 #define __LIB_STDINT_H
 
+#define NULL ((void *)0)
+#define true 1
+#define false 0
+
 typedef signed char int8_t;
 typedef signed short int16_t;
 typedef signed int int32_t;
@@ -11,4 +15,6 @@ typedef unsigned short uint16_t;
 typedef unsigned int uint32_t;
 typedef unsigned long long uint64_t;
 
+typedef uint8_t bool;
+
 #endif // __LIB_STDINT_H

+ 5 - 1
makefile

@@ -12,7 +12,7 @@ CFLAGS = -Wall $(LIB) -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototype
 LDFLAGS = -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_BIN_DIR)/kernel.map
 OBJS = $(BUID_O_DIR)/main.o $(BUID_O_DIR)/init.o $(BUID_O_DIR)/interrupt.o  \
 	$(BUID_O_DIR)/timer.o $(BUID_O_DIR)/kernel.o $(BUID_O_DIR)/print.o   \
-	$(BUID_O_DIR)/debug.o $(BUID_O_DIR)/string.o
+	$(BUID_O_DIR)/debug.o $(BUID_O_DIR)/string.o $(BUID_O_DIR)/bitmap.o
 
 ################################ C 代码编译 ################################
 $(BUID_O_DIR)/main.o: kernel/main.c lib/kernel/print.h lib/stdint.h kernel/init.h
@@ -33,6 +33,9 @@ $(BUID_O_DIR)/debug.o: kernel/debug.c kernel/debug.h lib/kernel/print.h lib/stdi
 $(BUID_O_DIR)/string.o: lib/string.c lib/string.h lib/stdint.h
 	$(CC) $(CFLAGS) $< -o $@
 
+$(BUID_O_DIR)/bitmap.o: lib/kernel/bitmap.c lib/kernel/bitmap.h lib/stdint.h lib/string.h
+	$(CC) $(CFLAGS) $< -o $@
+
 ################################ 汇编代码编译 ################################
 $(BUID_O_DIR)/kernel.o: kernel/kernel.S
 	$(AS) $(ASFLAGS) $< -o $@
@@ -60,6 +63,7 @@ mk_dir:
 ################################ 创建 DIS_IMG ################################
 create_img:
 	bximage -q -func=create -hd=30M $(DIS_IMG)
+	@echo "创建 $(DIS_IMG) 成功"
 
 hd:
 	dd if=$(BUILD_BIN_DIR)/mbr.bin of=$(DIS_IMG) bs=512 count=1 conv=notrunc