主頁 > 作業系統 > 基于mykernel 2.0撰寫一個作業系統內核

基于mykernel 2.0撰寫一個作業系統內核

2020-09-19 19:12:30 作業系統

資源下載:https://github.com/mengning/mykernel

實驗內容:

1、配置實驗環境,完成Linux內核編譯,

2、對系統原始碼進行修改,基于mykernel 2.0實作一個簡單的作業系統內核,

3、簡要分析作業系統內核核心功能及運行作業機制,

實驗環境:

VMWare虛擬機下的Ubuntu18.04.4,實驗采用的內核版本為linux-5.4.34,


1 內核編譯

1.1 準備作業

1.1.1 修改鏡像源地址

為了節省資源下載時間,使用國內鏡像源,

cd /etc/apt/
sudo cp sources.list sources.list.bk
sudo gedit sources.list
deb http://mirrors.aliyun.com/ubuntu bionic main multiverse restricted universe
deb http://mirrors.aliyun.com/ubuntu bionic-updates main multiverse restricted universe
deb http://mirrors.aliyun.com/ubuntu bionic-security main multiverse restricted universe
deb http://mirrors.aliyun.com/ubuntu bionic-proposed main multiverse restricted universe
deb http://mirrors.aliyun.com/ubuntu bionic-backports main multiverse restricted universe

將sources.list修改保存后,更新apt源,

sudo apt-get update

1.1.2 添加hosts映射

新增GitHub資源域名與對應IP的映射,

sudo vi /etc/hosts
151.101.76.133 raw.githubusercontent.com

1.1.3 安裝axel

多執行緒下載工具,用于下載Linux內核,

sudo apt install axel

1.2 下載內核補丁

wget https://raw.github.com/mengning/mykernel/master/mykernel-2.0_for_linux-5.4.34.patch

補丁檔案如下,根據diff對比,主要做了以下改動:

  • 在時鐘中斷時呼叫自定義的my_timer_handler函式,列印輸出>>>>>>>my_timer_handler here<<<<<<<<
  • 在start_kernel.h與timer.h中分別宣告my_start_kernel與my_timer_handler函式
  • 在main.c中呼叫my_start_kernel函式
  • 在Makefile中新增mykernel的編譯路徑
  • 創建mykernel的Makefile檔案
  • 撰寫myinterrupt.c與mymain.c檔案,mymain.c中模擬系統運行,每100000次回圈輸出一次
diff -Naur linux-5.4.34/arch/x86/kernel/time.c linux-5.4.34-mykernel/arch/x86/kernel/time.c
--- linux-5.4.34/arch/x86/kernel/time.c	2020-04-21 15:05:05.000000000 +0800
+++ linux-5.4.34-mykernel/arch/x86/kernel/time.c	2020-04-25 21:58:16.436717811 +0800
@@ -16,6 +16,7 @@
 #include <linux/irq.h>
 #include <linux/i8253.h>
 #include <linux/time.h>
+#include <linux/timer.h>
 #include <linux/export.h>
 
 #include <asm/vsyscall.h>
@@ -59,6 +60,7 @@
 static irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
 	global_clock_event->event_handler(global_clock_event);
+    	my_timer_handler();
 	return IRQ_HANDLED;
 }
 
diff -Naur linux-5.4.34/include/linux/start_kernel.h linux-5.4.34-mykernel/include/linux/start_kernel.h
--- linux-5.4.34/include/linux/start_kernel.h	2020-04-21 15:05:05.000000000 +0800
+++ linux-5.4.34-mykernel/include/linux/start_kernel.h	2020-04-25 22:00:17.304717811 +0800
@@ -9,6 +9,7 @@
    up something else. */
 
 extern asmlinkage void __init start_kernel(void);
+extern void __init my_start_kernel(void);
 extern void __init arch_call_rest_init(void);
 extern void __ref rest_init(void);
 
diff -Naur linux-5.4.34/include/linux/timer.h linux-5.4.34-mykernel/include/linux/timer.h
--- linux-5.4.34/include/linux/timer.h	2020-04-21 15:05:05.000000000 +0800
+++ linux-5.4.34-mykernel/include/linux/timer.h	2020-04-25 21:56:45.064717811 +0800
@@ -193,6 +193,8 @@
 
 extern void init_timers(void);
 extern void run_local_timers(void);
+extern void my_timer_handler(void);
+
 struct hrtimer;
 extern enum hrtimer_restart it_real_fn(struct hrtimer *);
 
diff -Naur linux-5.4.34/init/main.c linux-5.4.34-mykernel/init/main.c
--- linux-5.4.34/init/main.c	2020-04-21 15:05:05.000000000 +0800
+++ linux-5.4.34-mykernel/init/main.c	2020-04-25 22:01:13.476717811 +0800
@@ -781,6 +781,7 @@
 	arch_post_acpi_subsys_init();
 	sfi_init_late();
 
+    	my_start_kernel();
 	/* Do the rest non-__init'ed, we're now alive */
 	arch_call_rest_init();
 }
diff -Naur linux-5.4.34/Makefile linux-5.4.34-mykernel/Makefile
--- linux-5.4.34/Makefile	2020-04-21 15:05:05.000000000 +0800
+++ linux-5.4.34-mykernel/Makefile	2020-04-25 22:02:47.144717811 +0800
@@ -1012,7 +1012,7 @@
 export MODORDER := $(extmod-prefix)modules.order
 
 ifeq ($(KBUILD_EXTMOD),)
-core-y		+= kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y		+= kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ mykernel/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
diff -Naur linux-5.4.34/mykernel/Makefile linux-5.4.34-mykernel/mykernel/Makefile
--- linux-5.4.34/mykernel/Makefile	1970-01-01 08:00:00.000000000 +0800
+++ linux-5.4.34-mykernel/mykernel/Makefile	2020-04-25 17:14:13.537908421 +0800
@@ -0,0 +1,6 @@
+#
+# Makefile for the linux mykernel.
+#
+
+obj-y     = mymain.o myinterrupt.o
+
diff -Naur linux-5.4.34/mykernel/myinterrupt.c linux-5.4.34-mykernel/mykernel/myinterrupt.c
--- linux-5.4.34/mykernel/myinterrupt.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-5.4.34-mykernel/mykernel/myinterrupt.c	2020-04-25 19:09:50.612555999 +0800
@@ -0,0 +1,44 @@
+/*
+ *  linux/mykernel/myinterrupt.c
+ *
+ *  Kernel internal my_timer_handler
+ *
+ *  Copyright (C) 2013  Mengning
+ *
+ */
+#include <linux/kernel_stat.h>
+#include <linux/export.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/pid_namespace.h>
+#include <linux/notifier.h>
+#include <linux/thread_info.h>
+#include <linux/time.h>
+#include <linux/jiffies.h>
+#include <linux/posix-timers.h>
+#include <linux/cpu.h>
+#include <linux/syscalls.h>
+#include <linux/delay.h>
+#include <linux/tick.h>
+#include <linux/kallsyms.h>
+#include <linux/irq_work.h>
+#include <linux/sched.h>
+#include <linux/sched/sysctl.h>
+#include <linux/slab.h>
+
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/div64.h>
+#include <asm/timex.h>
+#include <asm/io.h>
+
+/*
+ * Called by timer interrupt.
+ */
+void my_timer_handler(void)
+{
+	pr_notice("\n>>>>>>>>>>>>>>>>>my_timer_handler here<<<<<<<<<<<<<<<<<<\n\n");
+}
diff -Naur linux-5.4.34/mykernel/mymain.c linux-5.4.34-mykernel/mykernel/mymain.c
--- linux-5.4.34/mykernel/mymain.c	1970-01-01 08:00:00.000000000 +0800
+++ linux-5.4.34-mykernel/mykernel/mymain.c	2020-04-25 19:10:27.635058000 +0800
@@ -0,0 +1,91 @@
+/*
+ *  linux/mykernel/mymain.c
+ *
+ *  Kernel internal my_start_kernel
+ *
+ *  Copyright (C) 2013  Mengning
+ *
+ */
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/kernel.h>
+#include <linux/syscalls.h>
+#include <linux/stackprotector.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/initrd.h>
+#include <linux/acpi.h>
+#include <linux/tty.h>
+#include <linux/percpu.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel_stat.h>
+#include <linux/start_kernel.h>
+#include <linux/security.h>
+#include <linux/smp.h>
+#include <linux/profile.h>
+#include <linux/rcupdate.h>
+#include <linux/moduleparam.h>
+#include <linux/kallsyms.h>
+#include <linux/writeback.h>
+#include <linux/cpu.h>
+#include <linux/cpuset.h>
+#include <linux/cgroup.h>
+#include <linux/efi.h>
+#include <linux/tick.h>
+#include <linux/interrupt.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
+#include <linux/unistd.h>
+#include <linux/rmap.h>
+#include <linux/mempolicy.h>
+#include <linux/key.h>
+#include <linux/buffer_head.h>
+#include <linux/debug_locks.h>
+#include <linux/debugobjects.h>
+#include <linux/lockdep.h>
+#include <linux/kmemleak.h>
+#include <linux/pid_namespace.h>
+#include <linux/device.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/idr.h>
+#include <linux/kgdb.h>
+#include <linux/ftrace.h>
+#include <linux/async.h>
+#include <linux/sfi.h>
+#include <linux/shmem_fs.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
+#include <linux/file.h>
+#include <linux/ptrace.h>
+#include <linux/blkdev.h>
+#include <linux/elevator.h>
+
+#include <asm/io.h>
+#include <asm/bugs.h>
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/cacheflush.h>
+
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/smp.h>
+#endif
+
+
+void __init my_start_kernel(void)
+{
+    int i = 0;
+    while(1)
+    {
+        i++;
+        if(i%100000 == 0)
+            pr_notice("my_start_kernel here  %d \n",i);
+            
+    }
+}
diff -Naur linux-5.4.34/mykernel/README.md linux-5.4.34-mykernel/mykernel/README.md
--- linux-5.4.34/mykernel/README.md	1970-01-01 08:00:00.000000000 +0800
+++ linux-5.4.34-mykernel/mykernel/README.md	2020-04-25 22:18:46.512717811 +0800
@@ -0,0 +1,21 @@
+mykernel 2.0
+==========
+Develop your own OS kernel by reusing Linux infrastructure, based on x86-64/Linux Kernel 5.4.34.
+
+## Set up mykernel 2.0 in Ubuntu 18.04
+
+```
+sudo apt install build-essential
+sudo apt install axel
+sudo apt install qemu # install QEMU
+sudo apt install libncurses-dev bison flex libssl-dev libelf-dev
+wget https://raw.github.com/mengning/mykernel/master/mykernel-2.0_for_linux-5.3.34.patch
+axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
+xz -d linux-5.4.34.tar.xz
+tar -xvf linux-5.4.34.tar
+cd linux-5.4.34
+patch -p1 < ../mykernel-2.0_for_linux-5.3.34.patch
+make defconfig # Default configuration is based on 'x86_64_defconfig'
+make -j$(nproc)
+qemu-system-x86_64 -kernel arch/x86/boot/bzImage
+```

1.3 下載內核

sudo axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar

1.4 安裝補丁

cd linux-5.4.34
sudo apt install patch
patch -p1 < ../mykernel-2.0_for_linux-5.4.34.patch

1.5 編譯內核

在虛擬機環境下,如果物理機支持超執行緒,可以配置虛擬機為雙核四執行緒,

編譯時間大致四五分鐘左右,如果虛擬機默認配置單核單執行緒,使用defconfig需要較長的編譯時間,

sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev
make defconfig
make -j$(nproc)

1.6 安裝QEMU模擬器

此處QEMU用于模擬硬體設備,通過模擬一臺獨立運行作業系統的虛擬機,運行編譯后的系統,

sudo apt install qemu # install QEMU
qemu-system-x86_64 -kernel arch/x86/boot/bzImage


至此,Linux內核編譯完成,大致的配置流程為:

  • 下載內核補丁
  • 下載系統內核
  • 通過給系統打補丁后編譯運行,觀察內核運行與中斷的輸出

2 修改內核

首先,在mykernel目錄下創建mypcb.h頭檔案:

  • Thread結構體模擬指令指標與堆疊指標

  • PCB結構體實作行程控制塊,主要包含行程句柄,狀態,堆疊,執行緒資訊,行程函式等,next以鏈表形式鏈接行程

#define MAX_TASK_NUM        4
#define KERNEL_STACK_SIZE   1024*2

struct Thread {
    unsigned long		ip;
    unsigned long		sp;
};

typedef struct PCB{
    int pid;
    volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
    unsigned long stack[KERNEL_STACK_SIZE];
    struct Thread thread;
    unsigned long	task_entry;
    struct PCB *next;
}tPCB;

void my_schedule(void);

之后創建myinterrupt.c檔案,實作中斷效果以及行程間的切換:

#include "mypcb.h"

extern tPCB task[MAX_TASK_NUM];
extern tPCB * my_current_task;
extern volatile int my_need_sched;
volatile int time_count = 0;

/*
 * Called by timer interrupt.
 * it runs in the name of current running process,
 * so it use kernel stack of current running process
 */
void my_timer_handler(void)
{
    if(time_count%1000 == 0 && my_need_sched != 1)
    {
        printk(KERN_NOTICE ">>>my_timer_handler here<<<\n");
        my_need_sched = 1;
    } 
    time_count ++ ;  
    return;  	
}

void my_schedule(void)
{
    tPCB * next;
    tPCB * prev;

    if(my_current_task == NULL 
        || my_current_task->next == NULL)
    {
    	return;
    }
    printk(KERN_NOTICE ">>>my_schedule<<<\n");
    /* schedule */
    next = my_current_task->next;
    prev = my_current_task;
    if(next->state == 0)
    {        
    	my_current_task = next; 
    	printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);  
    	/* switch to next process */
    	asm volatile(	
        	"pushq %%rbp\n\t"
        	"movq %%rsp,%0\n\t"
        	"movq %2,%%rsp\n\t"
        	"movq $1f,%1\n\t"
        	"pushq %3\n\t" 
        	"ret\n\t"
        	"1:\t"
        	"popq %%rbp\n\t"
        	: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
        	: "m" (next->thread.sp),"m" (next->thread.ip)
    	); 
    }  
    return;	
}

最后在mymain.c中,根據0號行程fork出其他行程,形成行程的環狀呼叫:

#include "mypcb.h"

tPCB task[MAX_TASK_NUM];
tPCB * my_current_task = NULL;
volatile int my_need_sched = 0;

void my_process(void);

void __init my_start_kernel(void)
{
    int pid = 0;
    int i;
    /* Initialize process 0*/
    task[pid].pid = pid;
    task[pid].state = 0;
    task[pid].task_entry = task[pid].thread.ip = (unsigned long)my_process;
    task[pid].thread.sp = (unsigned long)&task[pid].stack[KERNEL_STACK_SIZE-1];
    task[pid].next = &task[pid];
    /*fork more process */
    for(i=1;i<MAX_TASK_NUM;i++)
    {
        memcpy(&task[i],&task[0],sizeof(tPCB));
        task[i].pid = i;
	    task[i].thread.sp = (unsigned long)(&task[i].stack[KERNEL_STACK_SIZE-1]);
        task[i].next = task[i-1].next;
        task[i-1].next = &task[i];
    }
    /* start process 0 by task[0] */
    pid = 0;
    my_current_task = &task[pid];
	asm volatile(
    	"movq %1,%%rsp\n\t"
    	"pushq %1\n\t"
    	"pushq %0\n\t"
    	"ret\n\t"
    	: 
    	: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)
	);
} 

int i = 0;

void my_process(void)
{    
    while(1)
    {
        i++;
        if(i%10000000 == 0)
        {
            printk(KERN_NOTICE "this is process %d -\n",my_current_task->pid);
            if(my_need_sched == 1)
            {
                my_need_sched = 0;
        	    my_schedule();
        	}
        	printk(KERN_NOTICE "this is process %d +\n",my_current_task->pid);
        }     
    }
}

以上代碼的核心在于兩段內嵌匯編代碼,mymain.c與myinterrupt.c中分別實作了0號行程的啟動與行程間切換:

asm volatile(
    	"movq %1,%%rsp\n\t" 	/* set task[pid].thread.sp to rsp */
    	"pushq %1\n\t" 	        /* push rbp */
    	"pushq %0\n\t" 	        /* push task[pid].thread.ip */
    	"ret\n\t" 	        /* pop task[pid].thread.ip to rip */
    	: 
    	: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)	/* input c or d mean %ecx/%edx*/
	);

mymain.c中將0號行程堆疊頂資訊存入rsp暫存器,通過將當前行程rbp與指令指標壓堆疊,再借用ret指令回傳0號行程ip指向的my_process函式執行,

asm volatile(	
        	"pushq %%rbp\n\t" 	/* save rbp of prev */
        	"movq %%rsp,%0\n\t" 	/* save rsp of prev */
        	"movq %2,%%rsp\n\t"     /* restore  rsp of next */
        	"movq $1f,%1\n\t"       /* save rip of prev */	
        	"pushq %3\n\t" 
        	"ret\n\t" 	        /* restore  rip of next */
        	"1:\t"                  /* next process start here */
        	"popq %%rbp\n\t"
        	: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
        	: "m" (next->thread.sp),"m" (next->thread.ip)
    	); 

myinterrupt.c中先將當前的rbp壓堆疊,然后保存當前行程的rsp資訊,完成后將其更新為下一個行程的rsp,

之后將即將運行的行程IP入堆疊,通過ret指令將下一個行程的IP送入rip暫存器,

最后將切換后的行程堆疊基地址從堆疊中恢復到rbp暫存器中,

3 核心功能

Linux作業系統主要有以下核心功能:

  • 行程管理

    負責管理CPU資源,以便讓各個行程可以以盡量公平的方式訪問CPU,

  • 記憶體管理

    負責管理Memory(記憶體)資源,以便讓各個行程可以安全地共享機器的記憶體資源,

  • 檔案系統

    Linux內核將不同功能的外部設備,抽象為統一的檔案操作介面(open、close、read、write等),

  • 網路管理

    負責管理系統的網路設備,并實作各類網路標準,

  • 硬體驅動

    將系統操作映射到物理設備,除了處理器,記憶體等個別物體外,一般設備控制操作都由尋址設備相關的代碼進行,

  • 行程間通信

    不管理硬體,只負責Linux系統中行程之間的通信,

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/83137.html

標籤:Linux

上一篇:發現了一個win10的bug

下一篇:Linux 行程狀態

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more