mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 15:26:47 +00:00
Merge branch 'data_structure'
This commit is contained in:
commit
53fcc0c1e5
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -110,7 +110,9 @@
|
|||||||
"boot_info.h": "c",
|
"boot_info.h": "c",
|
||||||
"pci.h": "c",
|
"pci.h": "c",
|
||||||
"time.h": "c",
|
"time.h": "c",
|
||||||
"ia64_msi.h": "c"
|
"ia64_msi.h": "c",
|
||||||
|
"errno.h": "c",
|
||||||
|
"bug.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"esbonio.sphinx.confDir": ""
|
||||||
|
@ -18,7 +18,7 @@ LD_LIST := head.o
|
|||||||
OBJ_LIST := head.o
|
OBJ_LIST := head.o
|
||||||
|
|
||||||
|
|
||||||
kernel_subdirs := common driver process debug filesystem time arch exception mm smp sched syscall
|
kernel_subdirs := common driver process debug filesystem time arch exception mm smp sched syscall ktest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ all: kernel
|
|||||||
|
|
||||||
# 重新链接
|
# 重新链接
|
||||||
echo "Re-Linking kernel..."
|
echo "Re-Linking kernel..."
|
||||||
ld -b elf64-x86-64 -z muldefs -o kernel head.o main.o $(shell find . -name "*.o") -T link.lds
|
ld -b elf64-x86-64 -z muldefs -o kernel head.o main.o $(shell find . -name "*.o") ./debug/kallsyms.o -T link.lds
|
||||||
echo "Generating kernel ELF file..."
|
echo "Generating kernel ELF file..."
|
||||||
# 生成内核文件
|
# 生成内核文件
|
||||||
objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
|
objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
|
||||||
|
@ -3,7 +3,7 @@ CFLAGS += -I .
|
|||||||
|
|
||||||
kernel_common_subdirs:=libELF math
|
kernel_common_subdirs:=libELF math
|
||||||
|
|
||||||
all: glib.o printk.o cpu.o
|
all: glib.o printk.o cpu.o bitree.o
|
||||||
@list='$(kernel_common_subdirs)'; for subdir in $$list; do \
|
@list='$(kernel_common_subdirs)'; for subdir in $$list; do \
|
||||||
echo "make all in $$subdir";\
|
echo "make all in $$subdir";\
|
||||||
cd $$subdir;\
|
cd $$subdir;\
|
||||||
@ -19,3 +19,6 @@ printk.o: printk.c
|
|||||||
|
|
||||||
cpu.o: cpu.c
|
cpu.o: cpu.c
|
||||||
gcc $(CFLAGS) -c cpu.c -o cpu.o
|
gcc $(CFLAGS) -c cpu.c -o cpu.o
|
||||||
|
|
||||||
|
bitree.o: bitree.c
|
||||||
|
gcc $(CFLAGS) -c bitree.c -o bitree.o
|
206
kernel/common/bitree.c
Normal file
206
kernel/common/bitree.c
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
#include "bitree.h"
|
||||||
|
#include <mm/slab.h>
|
||||||
|
#include <common/errno.h>
|
||||||
|
#include <debug/bug.h>
|
||||||
|
|
||||||
|
#define smaller(root, a, b) (root->cmp((a)->value, (b)->value) == -1)
|
||||||
|
#define equal(root, a, b) (root->cmp((a)->value, (b)->value) == 0)
|
||||||
|
#define greater(root, a, b) (root->cmp((a)->value, (b)->value) == 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建二叉搜索树
|
||||||
|
*
|
||||||
|
* @param node 根节点
|
||||||
|
* @param cmp 比较函数
|
||||||
|
* @param release 用来释放结点的value的函数
|
||||||
|
* @return struct bt_root_t* 树根结构体
|
||||||
|
*/
|
||||||
|
struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(void *a, void *b), int (*release)(void *value))
|
||||||
|
{
|
||||||
|
if (node == NULL || cmp == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
struct bt_root_t *root = (struct bt_root_t *)kmalloc(sizeof(struct bt_root_t), 0);
|
||||||
|
memset((void *)root, 0, sizeof(struct bt_root_t));
|
||||||
|
root->bt_node = node;
|
||||||
|
root->cmp = cmp;
|
||||||
|
root->release = release;
|
||||||
|
root->size = (node == NULL) ? 0 : 1;
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建结点
|
||||||
|
*
|
||||||
|
* @param left 左子节点
|
||||||
|
* @param right 右子节点
|
||||||
|
* @param value 当前节点的值
|
||||||
|
* @return struct bt_node_t*
|
||||||
|
*/
|
||||||
|
struct bt_node_t *bt_create_node(struct bt_node_t *left, struct bt_node_t *right, struct bt_node_t *parent, void *value)
|
||||||
|
{
|
||||||
|
struct bt_node_t *node = (struct bt_node_t *)kmalloc(sizeof(struct bt_node_t), 0);
|
||||||
|
FAIL_ON_TO(node == NULL, nomem);
|
||||||
|
memset((void *)node, 0, sizeof(struct bt_node_t));
|
||||||
|
|
||||||
|
node->left = left;
|
||||||
|
node->right = right;
|
||||||
|
node->value = value;
|
||||||
|
node->parent = parent;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
nomem:;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 插入结点
|
||||||
|
*
|
||||||
|
* @param root 树根结点
|
||||||
|
* @param value 待插入结点的值
|
||||||
|
* @return int 返回码
|
||||||
|
*/
|
||||||
|
int bt_insert(struct bt_root_t *root, void *value)
|
||||||
|
{
|
||||||
|
if (root == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
struct bt_node_t *this_node = root->bt_node;
|
||||||
|
struct bt_node_t *last_node = NULL;
|
||||||
|
struct bt_node_t *insert_node = bt_create_node(NULL, NULL, NULL, value);
|
||||||
|
FAIL_ON_TO((uint64_t)insert_node == (uint64_t)(-ENOMEM), failed);
|
||||||
|
|
||||||
|
while (this_node != NULL)
|
||||||
|
{
|
||||||
|
last_node = this_node;
|
||||||
|
if (smaller(root, insert_node, this_node))
|
||||||
|
this_node = this_node->left;
|
||||||
|
else
|
||||||
|
this_node = this_node->right;
|
||||||
|
}
|
||||||
|
|
||||||
|
insert_node->parent = last_node;
|
||||||
|
if (unlikely(last_node == NULL))
|
||||||
|
root->bt_node = insert_node;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (smaller(root, insert_node, last_node))
|
||||||
|
last_node->left = insert_node;
|
||||||
|
else
|
||||||
|
last_node->right = insert_node;
|
||||||
|
}
|
||||||
|
++root->size;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
failed:;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 搜索值为value的结点
|
||||||
|
*
|
||||||
|
* @param value 值
|
||||||
|
* @param ret_addr 返回的结点基地址
|
||||||
|
* @return int 错误码
|
||||||
|
*/
|
||||||
|
int bt_query(struct bt_root_t *root, void *value, uint64_t *ret_addr)
|
||||||
|
{
|
||||||
|
struct bt_node_t *this_node = root->bt_node;
|
||||||
|
struct bt_node_t tmp_node = {0};
|
||||||
|
tmp_node.value = value;
|
||||||
|
|
||||||
|
// 如果返回地址为0
|
||||||
|
if (ret_addr == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
while (this_node != NULL && !equal(root, this_node, &tmp_node))
|
||||||
|
{
|
||||||
|
if (smaller(root, &tmp_node, this_node))
|
||||||
|
this_node = this_node->left;
|
||||||
|
else
|
||||||
|
this_node = this_node->right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this_node != NULL && equal(root, this_node, &tmp_node))
|
||||||
|
{
|
||||||
|
*ret_addr = (uint64_t)this_node;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 找不到则返回-1,且addr设为0
|
||||||
|
*ret_addr = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct bt_node_t *bt_get_minimum(struct bt_node_t *this_node)
|
||||||
|
{
|
||||||
|
while (this_node->left != NULL)
|
||||||
|
this_node = this_node->left;
|
||||||
|
return this_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 删除结点
|
||||||
|
*
|
||||||
|
* @param root 树根
|
||||||
|
* @param value 待删除结点的值
|
||||||
|
* @return int 返回码
|
||||||
|
*/
|
||||||
|
int bt_delete(struct bt_root_t *root, void *value)
|
||||||
|
{
|
||||||
|
uint64_t tmp_addr;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
// 寻找待删除结点
|
||||||
|
retval = bt_query(root, value, &tmp_addr);
|
||||||
|
if (retval != 0 || tmp_addr == NULL)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
struct bt_node_t *this_node = (struct bt_node_t *)tmp_addr;
|
||||||
|
struct bt_node_t *to_delete = NULL, *to_delete_son = NULL;
|
||||||
|
if (this_node->left == NULL || this_node->right == NULL)
|
||||||
|
to_delete = this_node;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to_delete = bt_get_minimum(this_node->right);
|
||||||
|
// 释放要被删除的值,并把下一个结点的值替换上来
|
||||||
|
root->release(this_node->value);
|
||||||
|
this_node->value = to_delete->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_delete->left != NULL)
|
||||||
|
to_delete_son = to_delete->left;
|
||||||
|
else
|
||||||
|
to_delete_son = to_delete->right;
|
||||||
|
|
||||||
|
if (to_delete_son != NULL)
|
||||||
|
to_delete_son->parent = to_delete->parent;
|
||||||
|
|
||||||
|
if (to_delete->parent == NULL)
|
||||||
|
root->bt_node = to_delete_son;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (to_delete->parent->left == to_delete)
|
||||||
|
to_delete->parent->left = to_delete_son;
|
||||||
|
else
|
||||||
|
to_delete->parent->right = to_delete_son;
|
||||||
|
}
|
||||||
|
|
||||||
|
--root->size;
|
||||||
|
// 释放最终要删除的结点的对象
|
||||||
|
kfree(to_delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 释放整个二叉搜索树
|
||||||
|
*
|
||||||
|
* @param root 树的根节点
|
||||||
|
* @return int 错误码
|
||||||
|
*/
|
||||||
|
int bt_destroy_tree(struct bt_root_t *root)
|
||||||
|
{
|
||||||
|
// todo: 待kfifo完成后,使用kfifo队列来辅助destroy
|
||||||
|
return -1;
|
||||||
|
}
|
79
kernel/common/bitree.h
Normal file
79
kernel/common/bitree.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <common/glib.h>
|
||||||
|
|
||||||
|
struct bt_node_t
|
||||||
|
{
|
||||||
|
struct bt_node_t *left;
|
||||||
|
struct bt_node_t *right;
|
||||||
|
struct bt_node_t *parent;
|
||||||
|
void *value; // 数据
|
||||||
|
|
||||||
|
} __attribute__((aligned(sizeof(long))));
|
||||||
|
|
||||||
|
struct bt_root_t
|
||||||
|
{
|
||||||
|
struct bt_node_t *bt_node;
|
||||||
|
int32_t size; // 树中的元素个数
|
||||||
|
int (*cmp)(void *a, void *b); // 比较函数 a>b 返回1, a==b返回0, a<b返回-1
|
||||||
|
/**
|
||||||
|
* @brief 释放结点的value的函数
|
||||||
|
* @param value 结点的值
|
||||||
|
*/
|
||||||
|
int (*release)(void *value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建二叉搜索树
|
||||||
|
*
|
||||||
|
* @param node 根节点
|
||||||
|
* @param cmp 比较函数
|
||||||
|
* @param release 用来释放结点的value的函数
|
||||||
|
* @return struct bt_root_t* 树根结构体
|
||||||
|
*/
|
||||||
|
struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(void *a, void *b), int (*release)(void *value));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 创建结点
|
||||||
|
*
|
||||||
|
* @param left 左子节点
|
||||||
|
* @param right 右子节点
|
||||||
|
* @param value 当前节点的值
|
||||||
|
* @return struct bt_node_t*
|
||||||
|
*/
|
||||||
|
struct bt_node_t *bt_create_node(struct bt_node_t *left, struct bt_node_t *right, struct bt_node_t *parent, void *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 插入结点
|
||||||
|
*
|
||||||
|
* @param root 树根结点
|
||||||
|
* @param value 待插入结点的值
|
||||||
|
* @return int 返回码
|
||||||
|
*/
|
||||||
|
int bt_insert(struct bt_root_t *root, void *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 搜索值为value的结点
|
||||||
|
*
|
||||||
|
* @param root 树根结点
|
||||||
|
* @param value 值
|
||||||
|
* @param ret_addr 返回的结点基地址
|
||||||
|
* @return int 错误码
|
||||||
|
*/
|
||||||
|
int bt_query(struct bt_root_t *root, void *value, uint64_t *ret_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 删除结点
|
||||||
|
*
|
||||||
|
* @param root 树根
|
||||||
|
* @param value 待删除结点的值
|
||||||
|
* @return int 返回码
|
||||||
|
*/
|
||||||
|
int bt_delete(struct bt_root_t *root, void *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 释放整个二叉搜索树
|
||||||
|
*
|
||||||
|
* @param root
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int bt_destroy_tree(struct bt_root_t *root);
|
@ -21,29 +21,3 @@
|
|||||||
/// 长度
|
/// 长度
|
||||||
extern unsigned int boot_info_size;
|
extern unsigned int boot_info_size;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化,定义在具体实现中
|
|
||||||
* @return true 成功
|
|
||||||
* @return false 成功
|
|
||||||
*/
|
|
||||||
extern int init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取物理内存信息
|
|
||||||
* @return resource_t 物理内存资源信息
|
|
||||||
*/
|
|
||||||
//extern resource_t get_memory(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取 clint 信息
|
|
||||||
* @return resource_t clint 资源信息
|
|
||||||
*/
|
|
||||||
//extern resource_t get_clint(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取 plic 信息
|
|
||||||
* @return resource_t plic 资源信息
|
|
||||||
*/
|
|
||||||
//extern resource_t get_plic(void);
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,3 +12,10 @@
|
|||||||
kwarn("Assertion failed at %s:%d", __FILE__, __LINE__); \
|
kwarn("Assertion failed at %s:%d", __FILE__, __LINE__); \
|
||||||
unlikely(__ret_warn_on); \
|
unlikely(__ret_warn_on); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define FAIL_ON_TO(condition, to) ({ \
|
||||||
|
int __ret_warn_on = !!(condition); \
|
||||||
|
if (unlikely(__ret_warn_on)) \
|
||||||
|
goto to; \
|
||||||
|
unlikely(__ret_warn_on); \
|
||||||
|
})
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <exception/irq.h>
|
#include <exception/irq.h>
|
||||||
#include <driver/interrupt/apic/apic.h>
|
#include <driver/interrupt/apic/apic.h>
|
||||||
|
|
||||||
spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁(在usb_init中被初始化)
|
spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化)
|
||||||
|
|
||||||
static int xhci_ctrl_count = 0; // xhci控制器计数
|
static int xhci_ctrl_count = 0; // xhci控制器计数
|
||||||
|
|
||||||
@ -123,13 +123,6 @@ hardware_intr_controller xhci_hc_intr_controller =
|
|||||||
ptr->cycle = 1; \
|
ptr->cycle = 1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define FAIL_ON(value, to) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (unlikely(value != 0)) \
|
|
||||||
goto to; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
// Common TRB types
|
// Common TRB types
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -387,7 +380,7 @@ static int xhci_hc_pair_ports(int id)
|
|||||||
|
|
||||||
uint32_t next_off = xhci_hc[id].ext_caps_off;
|
uint32_t next_off = xhci_hc[id].ext_caps_off;
|
||||||
uint32_t offset, cnt;
|
uint32_t offset, cnt;
|
||||||
uint16_t protocol_flags;
|
uint16_t protocol_flags = 0;
|
||||||
|
|
||||||
// 寻找所有的usb2端口
|
// 寻找所有的usb2端口
|
||||||
while (next_off)
|
while (next_off)
|
||||||
@ -560,7 +553,7 @@ uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
|
|||||||
struct msi_desc_t msi_desc;
|
struct msi_desc_t msi_desc;
|
||||||
memset(&msi_desc, 0, sizeof(struct msi_desc_t));
|
memset(&msi_desc, 0, sizeof(struct msi_desc_t));
|
||||||
|
|
||||||
msi_desc.pci_dev = (struct pci_device_structure_header_t*)xhci_hc[cid].pci_dev_hdr;
|
msi_desc.pci_dev = (struct pci_device_structure_header_t *)xhci_hc[cid].pci_dev_hdr;
|
||||||
msi_desc.assert = info->assert;
|
msi_desc.assert = info->assert;
|
||||||
msi_desc.edge_trigger = info->edge_trigger;
|
msi_desc.edge_trigger = info->edge_trigger;
|
||||||
msi_desc.processor = info->processor;
|
msi_desc.processor = info->processor;
|
||||||
@ -854,12 +847,12 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 关闭legacy支持
|
// 关闭legacy支持
|
||||||
FAIL_ON(xhci_hc_stop_legacy(cid), failed);
|
FAIL_ON_TO(xhci_hc_stop_legacy(cid), failed);
|
||||||
|
|
||||||
// 重置xhci控制器
|
// 重置xhci控制器
|
||||||
FAIL_ON(xhci_hc_reset(cid), failed);
|
FAIL_ON_TO(xhci_hc_reset(cid), failed);
|
||||||
// 端口配对
|
// 端口配对
|
||||||
FAIL_ON(xhci_hc_pair_ports(cid), failed);
|
FAIL_ON_TO(xhci_hc_pair_ports(cid), failed);
|
||||||
|
|
||||||
// ========== 设置USB host controller =========
|
// ========== 设置USB host controller =========
|
||||||
// 获取页面大小
|
// 获取页面大小
|
||||||
@ -900,7 +893,7 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
|
|||||||
// 写入设备通知控制寄存器
|
// 写入设备通知控制寄存器
|
||||||
xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持
|
xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持
|
||||||
|
|
||||||
FAIL_ON(xhci_hc_init_intr(cid), failed_free_dyn);
|
FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn);
|
||||||
++xhci_ctrl_count;
|
++xhci_ctrl_count;
|
||||||
spin_unlock(&xhci_controller_init_lock);
|
spin_unlock(&xhci_controller_init_lock);
|
||||||
return;
|
return;
|
||||||
|
8
kernel/ktest/Makefile
Normal file
8
kernel/ktest/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
CFLAGS += -I .
|
||||||
|
|
||||||
|
|
||||||
|
all: bitree.o
|
||||||
|
|
||||||
|
bitree.o: test-bitree.c
|
||||||
|
gcc $(CFLAGS) -c test-bitree.c -o test-bitree.o
|
4
kernel/ktest/ktest.h
Normal file
4
kernel/ktest/ktest.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <common/sys/types.h>
|
||||||
|
|
||||||
|
uint64_t ktest_test_bitree(uint64_t arg);
|
27
kernel/ktest/ktest_utils.h
Normal file
27
kernel/ktest/ktest_utils.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common/printk.h>
|
||||||
|
#include <common/compiler.h>
|
||||||
|
|
||||||
|
#define assert(condition) ({ \
|
||||||
|
int __condition = !!(condition); \
|
||||||
|
if (unlikely(!(__condition))) \
|
||||||
|
{ \
|
||||||
|
printk("[ kTEST FAILED ] Ktest Assertion Failed, file:%s, Line:%d\n", __FILE__, __LINE__); \
|
||||||
|
} \
|
||||||
|
likely(__condition); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define kTEST(...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
printk("[ kTEST ] file:%s, Line:%d\t", __FILE__, __LINE__); \
|
||||||
|
printk(__VA_ARGS__); \
|
||||||
|
printk("\n"); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 测试用例函数表
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef long (*ktest_case_table)(uint64_t arg0, uint64_t arg1);
|
132
kernel/ktest/test-bitree.c
Normal file
132
kernel/ktest/test-bitree.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include "ktest.h"
|
||||||
|
#include <ktest/ktest_utils.h>
|
||||||
|
|
||||||
|
#include <common/unistd.h>
|
||||||
|
#include <common/kprint.h>
|
||||||
|
#include <common/bitree.h>
|
||||||
|
#include <common/errno.h>
|
||||||
|
|
||||||
|
#include <mm/slab.h>
|
||||||
|
|
||||||
|
struct test_value_t
|
||||||
|
{
|
||||||
|
uint64_t tv;
|
||||||
|
};
|
||||||
|
static int compare(void *a, void *b)
|
||||||
|
{
|
||||||
|
if (((struct test_value_t *)a)->tv > ((struct test_value_t *)b)->tv)
|
||||||
|
return 1;
|
||||||
|
else if (((struct test_value_t *)a)->tv == ((struct test_value_t *)b)->tv)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int release(void *value)
|
||||||
|
{
|
||||||
|
// kdebug("release");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 测试创建二叉树
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
static long ktest_bitree_case1(uint64_t arg0, uint64_t arg1)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
// ========== 测试创建树
|
||||||
|
struct test_value_t *tv1 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
|
||||||
|
tv1->tv = 20;
|
||||||
|
struct bt_node_t *rn = bt_create_node(NULL, NULL, NULL, tv1);
|
||||||
|
|
||||||
|
assert(rn != NULL);
|
||||||
|
assert((int64_t)rn != (-EINVAL));
|
||||||
|
assert(rn->value == tv1);
|
||||||
|
|
||||||
|
struct bt_root_t *tree = bt_create_tree(rn, compare, release);
|
||||||
|
assert(tree != NULL);
|
||||||
|
assert(tree->bt_node == rn);
|
||||||
|
assert(tree->cmp == compare);
|
||||||
|
assert(tree->release == release);
|
||||||
|
assert(tree->size == 1);
|
||||||
|
|
||||||
|
// ========= 向树中插入数据10、30
|
||||||
|
struct test_value_t *tv2 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
|
||||||
|
assert(tv2 != NULL);
|
||||||
|
tv2->tv = 10;
|
||||||
|
{
|
||||||
|
int last_size = tree->size;
|
||||||
|
val = bt_insert(tree, tv2);
|
||||||
|
assert(val == 0);
|
||||||
|
assert(last_size + 1 == tree->size);
|
||||||
|
}
|
||||||
|
struct test_value_t *tv3 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
|
||||||
|
assert(tv3 != NULL);
|
||||||
|
tv3->tv = 30;
|
||||||
|
{
|
||||||
|
int last_size = tree->size;
|
||||||
|
val = bt_insert(tree, tv3);
|
||||||
|
assert(val == 0);
|
||||||
|
assert(last_size + 1 == tree->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测树的形状
|
||||||
|
assert(((struct test_value_t *)tree->bt_node->left->value)->tv == tv2->tv);
|
||||||
|
assert(((struct test_value_t *)tree->bt_node->right->value)->tv == tv3->tv);
|
||||||
|
|
||||||
|
// ========= 查询结点
|
||||||
|
// 查询值为tv2的结点
|
||||||
|
struct bt_node_t *node2;
|
||||||
|
assert(bt_query(tree, tv2, (uint64_t*)(&node2)) == 0);
|
||||||
|
assert(node2 != NULL);
|
||||||
|
assert(node2->value == tv2);
|
||||||
|
|
||||||
|
// ========= 插入第4个结点:15
|
||||||
|
struct test_value_t *tv4 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
|
||||||
|
assert(tv4 != NULL);
|
||||||
|
tv4->tv = 15;
|
||||||
|
{
|
||||||
|
int last_size = tree->size;
|
||||||
|
val = bt_insert(tree, tv4);
|
||||||
|
assert(val == 0);
|
||||||
|
assert(last_size + 1 == tree->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(((struct test_value_t *)node2->right->value)->tv == tv4->tv);
|
||||||
|
|
||||||
|
// ======= 查询不存在的值
|
||||||
|
struct bt_node_t *node_not_exists;
|
||||||
|
struct test_value_t *tv_not_exists = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
|
||||||
|
assert(tv_not_exists != NULL);
|
||||||
|
tv_not_exists->tv = 100;
|
||||||
|
assert(bt_query(tree, tv_not_exists, (uint64_t*)(&node_not_exists)) == -1);
|
||||||
|
// kdebug("node_not_exists.val=%d", ((struct test_value_t*)node_not_exists->value)->tv);
|
||||||
|
assert(node_not_exists == NULL);
|
||||||
|
|
||||||
|
// 删除根节点
|
||||||
|
assert(bt_delete(tree, rn->value) == 0);
|
||||||
|
assert(((struct test_value_t *)tree->bt_node->value)->tv != 20);
|
||||||
|
assert(tree->bt_node->right == NULL);
|
||||||
|
|
||||||
|
// 删除树
|
||||||
|
assert(bt_destroy_tree(tree) == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ktest_case_table kt_bitree_func_table[] = {
|
||||||
|
ktest_bitree_case1,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint64_t ktest_test_bitree(uint64_t arg)
|
||||||
|
{
|
||||||
|
kTEST("Testing bitree...");
|
||||||
|
for (int i = 0; i < sizeof(kt_bitree_func_table) / sizeof(ktest_case_table); ++i)
|
||||||
|
{
|
||||||
|
kTEST("Testing case %d", i);
|
||||||
|
kt_bitree_func_table[i](0, 0);
|
||||||
|
}
|
||||||
|
kdebug("bitree Test done.");
|
||||||
|
return 0;
|
||||||
|
}
|
@ -641,7 +641,7 @@ int mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_s
|
|||||||
{
|
{
|
||||||
if (unlikely(*pde_ptr != 0 && user))
|
if (unlikely(*pde_ptr != 0 && user))
|
||||||
{
|
{
|
||||||
kwarn("page already mapped!");
|
// kwarn("page already mapped!");
|
||||||
// 如果是用户态可访问的页,则释放当前新获取的物理页
|
// 如果是用户态可访问的页,则释放当前新获取的物理页
|
||||||
if (likely(((ul)phys_addr_start + length_mapped) < total_2M_pages)) // 校验是否为内存中的物理页
|
if (likely(((ul)phys_addr_start + length_mapped) < total_2M_pages)) // 校验是否为内存中的物理页
|
||||||
free_pages(Phy_to_2M_Page((ul)phys_addr_start + length_mapped), 1);
|
free_pages(Phy_to_2M_Page((ul)phys_addr_start + length_mapped), 1);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <syscall/syscall_num.h>
|
#include <syscall/syscall_num.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
|
||||||
|
#include <ktest/ktest.h>
|
||||||
|
|
||||||
spinlock_t process_global_pid_write_lock; // 增加pid的写锁
|
spinlock_t process_global_pid_write_lock; // 增加pid的写锁
|
||||||
long process_global_pid = 1; // 系统中最大的pid
|
long process_global_pid = 1; // 系统中最大的pid
|
||||||
@ -385,7 +386,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
|||||||
regs->rdi = argc;
|
regs->rdi = argc;
|
||||||
regs->rsi = (uint64_t)dst_argv;
|
regs->rsi = (uint64_t)dst_argv;
|
||||||
}
|
}
|
||||||
kdebug("execve ok");
|
// kdebug("execve ok");
|
||||||
|
|
||||||
regs->cs = USER_CS | 3;
|
regs->cs = USER_CS | 3;
|
||||||
regs->ds = USER_DS | 3;
|
regs->ds = USER_DS | 3;
|
||||||
@ -413,7 +414,8 @@ ul initial_kernel_thread(ul arg)
|
|||||||
fat32_init();
|
fat32_init();
|
||||||
usb_init();
|
usb_init();
|
||||||
|
|
||||||
|
pid_t test_thread_pid = kernel_thread(ktest_test_bitree, 1, 0);
|
||||||
|
kdebug("test_thread_pid=%d", test_thread_pid);
|
||||||
// 准备切换到用户态
|
// 准备切换到用户态
|
||||||
struct pt_regs *regs;
|
struct pt_regs *regs;
|
||||||
|
|
||||||
@ -569,7 +571,7 @@ void process_init()
|
|||||||
spin_init(&process_global_pid_write_lock);
|
spin_init(&process_global_pid_write_lock);
|
||||||
// 初始化进程的循环链表
|
// 初始化进程的循环链表
|
||||||
list_init(&initial_proc_union.pcb.list);
|
list_init(&initial_proc_union.pcb.list);
|
||||||
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核进程
|
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核线程
|
||||||
initial_proc_union.pcb.state = PROC_RUNNING;
|
initial_proc_union.pcb.state = PROC_RUNNING;
|
||||||
initial_proc_union.pcb.preempt_count = 0;
|
initial_proc_union.pcb.preempt_count = 0;
|
||||||
initial_proc_union.pcb.cpu_id = 0;
|
initial_proc_union.pcb.cpu_id = 0;
|
||||||
@ -586,7 +588,6 @@ void process_init()
|
|||||||
* @param stack_size 堆栈大小
|
* @param stack_size 堆栈大小
|
||||||
* @return unsigned long
|
* @return unsigned long
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size)
|
unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
@ -642,6 +643,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
if (process_copy_flags(clone_flags, tsk))
|
if (process_copy_flags(clone_flags, tsk))
|
||||||
goto copy_flags_failed;
|
goto copy_flags_failed;
|
||||||
|
|
||||||
|
kdebug("before copy mm");
|
||||||
// 拷贝内存空间分布结构体
|
// 拷贝内存空间分布结构体
|
||||||
if (process_copy_mm(clone_flags, tsk))
|
if (process_copy_mm(clone_flags, tsk))
|
||||||
goto copy_mm_failed;
|
goto copy_mm_failed;
|
||||||
|
@ -326,6 +326,17 @@ ul process_do_exit(ul code);
|
|||||||
*/
|
*/
|
||||||
void process_exit_notify();
|
void process_exit_notify();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化内核进程
|
||||||
|
*
|
||||||
|
* @param fn 目标程序的地址
|
||||||
|
* @param arg 向目标程序传入的参数
|
||||||
|
* @param flags
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
|
||||||
|
int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigned long flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 切换页表
|
* @brief 切换页表
|
||||||
* @param prev 前一个进程的pcb
|
* @param prev 前一个进程的pcb
|
||||||
|
Loading…
x
Reference in New Issue
Block a user