最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux內(nèi)核啟動(dòng)流程詳解(基于 5.15.119 源碼)

 更新時(shí)間:2026年05月18日 08:30:56   作者:magic_now  
文章詳細(xì)介紹了基于Linux 5.15.119源碼的x86_64架構(gòu)內(nèi)核啟動(dòng)流程,從GRUB加載bzImage到壓縮內(nèi)核解壓、初始化硬件、切換到保護(hù)模式、64位解壓入口,直至啟動(dòng)第一個(gè)用戶進(jìn)程/sbin/init的全過(guò)程,需要的朋友可以參考下

本文基于 Linux 5.15.119 實(shí)際源碼,從 GRUB 加載到第一個(gè)用戶進(jìn)程 /sbin/init 啟動(dòng),完整梳理 x86_64 架構(gòu)的內(nèi)核啟動(dòng)流程。

0. bzImage 的物理結(jié)構(gòu)

你執(zhí)行 make bzImage 編譯出來(lái)的文件,其實(shí)不是單一文件,而是兩部分拼接而成:

┌─────────────────┬─────────────────────────────┐
│   setup.bin     │    compressed/vmlinux       │
│  (實(shí)模式代碼)    │   (壓縮的真正的內(nèi)核)         │
│   ~30KB         │      幾MB ~ 幾十MB           │
└─────────────────┴─────────────────────────────┘
        ↑                              ↑
   從 bootsect 開(kāi)始              從 startup_32 開(kāi)始

Bootloader(GRUB)把它加載到內(nèi)存后,CPU 先執(zhí)行左邊的 setup.bin(還是古老的 16 位實(shí)模式),然后才進(jìn)入右邊的壓縮內(nèi)核。

拼接工作在 arch/x86/boot/tools/build.c 中完成。

1. GRUB 加載 bzImage

GRUB 讀取內(nèi)核文件開(kāi)頭的 內(nèi)核頭部(Kernel Header),獲取啟動(dòng)協(xié)議信息。

源碼位置arch/x86/boot/header.S

這個(gè)文件開(kāi)頭定義了一個(gè)兼容 MS-DOS 的頭部(MZ/PE 頭),讓 GRUB 能識(shí)別它:

#ifdef CONFIG_EFI_STUB
    .word   MZ_MAGIC            # "MZ" 魔數(shù)
#endif

頭部中包含了 GRUB 需要的關(guān)鍵字段:

字段含義
setup_sectssetup 部分占多少扇區(qū)
syssize內(nèi)核大小
version啟動(dòng)協(xié)議版本
cmd_line_ptr命令行參數(shù)地址
code32_start32 位代碼入口點(diǎn)

GRUB 根據(jù)這些信息把 bzImage 加載到內(nèi)存,然后把控制權(quán)交給 header.S 中的入口。

2. 實(shí)模式(16 位)—— 收集硬件信息

CPU 當(dāng)前狀態(tài):16 位實(shí)模式,只能直接訪問(wèn) 1MB 內(nèi)存,沒(méi)有內(nèi)存保護(hù)。

入口函數(shù):main()

源碼位置arch/x86/boot/main.c

這是整個(gè)內(nèi)核啟動(dòng)的第一個(gè) C 函數(shù)

void main(void)
{
    /* 把 header 里的信息復(fù)制到 boot_params */
    copy_boot_params();

    /* 初始化早期控制臺(tái) */
    console_init();

    /* 初始化堆內(nèi)存 */
    init_heap();

    /* 檢查 CPU 是否支持運(yùn)行這個(gè)內(nèi)核 */
    if (validate_cpu()) {
        puts("Unable to boot...");
        die();
    }

    /* 告訴 BIOS 我們要進(jìn) 64 位模式 */
    set_bios_mode();

    /* 用 BIOS 中斷探測(cè)內(nèi)存布局 */
    detect_memory();

    /* 設(shè)置鍵盤 */
    keyboard_init();

    /* 查詢各種 BIOS 信息 */
    query_ist();
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
    query_apm_bios();
#endif
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
    query_edd();
#endif

    /* 設(shè)置顯示模式 */
    set_video();

    /* ? 進(jìn)入保護(hù)模式 */
    go_to_protected_mode();
}

這些代碼看起來(lái)古老,但非常關(guān)鍵——它用 BIOS 中斷(int 0x10、int 0x15 等)收集硬件信息,全部存進(jìn)全局變量 boot_params,后面內(nèi)核會(huì)一直用它。

3. 切換到保護(hù)模式(32 位)

go_to_protected_mode() 定義在 arch/x86/boot/pm.c

void go_to_protected_mode(void)
{
    /* 關(guān)閉中斷,執(zhí)行實(shí)模式最后的鉤子 */
    realmode_switch_hook();

    /* 開(kāi)啟 A20 地址線(歷史遺留,為了訪問(wèn) 1MB 以上內(nèi)存) */
    if (enable_a20()) {
        puts("A20 gate not responding, unable to boot...\n");
        die();
    }

    /* 重置協(xié)處理器 */
    reset_coprocessor();

    /* 屏蔽所有中斷 */
    mask_all_interrupts();

    /* 設(shè)置 IDT 和 GDT */
    setup_idt();
    setup_gdt();

    /* ? 真正跳轉(zhuǎn)到保護(hù)模式 */
    protected_mode_jump(boot_params.hdr.code32_start,
                        (u32)&boot_params + (ds() << 4));
}

真正的切換發(fā)生在匯編文件 pmjump.S 中:

SYM_FUNC_START(protected_mode_jump)
    movl    %edx, %esi          # %edx = boot_params 指針

    movl    %cr0, %edx
    orb     $X86_CR0_PE, %dl    # 設(shè)置 CR0 的 PE (Protection Enable) 位
    movl    %edx, %cr0          # 打開(kāi)保護(hù)模式!

    # 長(zhǎng)跳轉(zhuǎn)到 32 位代碼段
    .byte   0x66, 0xea          # ljmpl 指令
    .long   .Lin_pm32           # 目標(biāo)偏移
    .word   __BOOT_CS           # 代碼段選擇子

.Lin_pm32:
    # 設(shè)置 32 位平坦模式的數(shù)據(jù)段
    movl    %ecx, %ds
    movl    %ecx, %es
    movl    %ecx, %fs
    movl    %ecx, %gs
    movl    %ecx, %ss

    jmpl    *%eax               # 跳轉(zhuǎn)到 32 位入口點(diǎn)

發(fā)生了什么:CPU 從 16 位實(shí)模式 → 32 位保護(hù)模式。現(xiàn)在能訪問(wèn) 4GB 內(nèi)存了,但還不是 64 位。

4. 32 位解壓入口

現(xiàn)在 CPU 開(kāi)始執(zhí)行 arch/x86/boot/compressed/head_64.S 中的 startup_32。

注意:文件名雖然是 head_64.S,但前面一大段是 .code32(32 位代碼)。

    .code32
SYM_FUNC_START(startup_32)
    cld
    cli                         # 關(guān)中斷

    # 計(jì)算"實(shí)際加載地址"與"編譯時(shí)地址"的偏差
    # 因?yàn)?bootloader 可能把內(nèi)核加載到了意料之外的位置
    leal    (BP_scratch+4)(%esi), %esp
    call    1f
1:  popl    %ebp
    subl    $ rva(1b), %ebp

    # 加載新的 GDT
    leal    rva(gdt)(%ebp), %eax
    movl    %eax, 2(%eax)
    lgdt    (%eax)

    # 設(shè)置數(shù)據(jù)段寄存器
    movl    $__BOOT_DS, %eax
    movl    %eax, %ds
    movl    %eax, %es
    movl    %eax, %fs
    movl    %eax, %gs
    movl    %eax, %ss

然后它繼續(xù):

  1. 建立臨時(shí)的 4GB 頁(yè)表(為進(jìn)入長(zhǎng)模式做準(zhǔn)備)
  2. 打開(kāi) PAE(Physical Address Extension,cr4 |= X86_CR4_PAE
  3. 設(shè)置 EFER.LME(Long Mode Enable)
  4. 啟用分頁(yè)(設(shè)置 cr0.PG = 1),CPU 自動(dòng)進(jìn)入兼容模式
  5. 長(zhǎng)跳轉(zhuǎn)到 64 位代碼

5. 64 位模式下的解壓

繼續(xù)在同一份 head_64.S 中,現(xiàn)在 CPU 運(yùn)行在 64 位模式了。

這段代碼的任務(wù)是:

  1. 找到壓縮的內(nèi)核數(shù)據(jù)(piggy.o 里包著 vmlinux.bin.gz.xz 等)
  2. 把它解壓到最終運(yùn)行地址
  3. 跳轉(zhuǎn)到解壓后的內(nèi)核入口

解壓完成后,它跳轉(zhuǎn)到真正的內(nèi)核入口——startup_64(注意:這是另一個(gè)文件里的同名符號(hào)!)。

相關(guān)文件

  • arch/x86/boot/compressed/head_64.S
  • arch/x86/boot/compressed/misc.c(解壓算法的 C 實(shí)現(xiàn))
  • arch/x86/boot/compressed/piggy.S(把壓縮后的內(nèi)核二進(jìn)制打包成匯編對(duì)象)

6. 真正的內(nèi)核 64 位入口

現(xiàn)在進(jìn)入 arch/x86/kernel/head_64.S 中的 startup_64。

這是編譯后的 vmlinux 的第一條指令,也是內(nèi)核真正開(kāi)始建立自己世界的地方。

    .code64
SYM_CODE_START_NOALIGN(startup_64)
    /* 設(shè)置棧(用 init_task 的棧) */
    leaq    (__end_init_task - FRAME_SIZE)(%rip), %rsp

    /* 調(diào)用 startup_64_setup_env 和 verify_cpu */
    leaq    _text(%rip), %rdi
    pushq   %rsi
    call    startup_64_setup_env
    popq    %rsi

    call    verify_cpu

    /* 修正頁(yè)表(內(nèi)核可能被加載到了與編譯地址不同的位置) */
    leaq    _text(%rip), %rdi
    pushq   %rsi
    call    __startup_64
    popq    %rsi

    /* 形成 CR3 值(頁(yè)表基址) */
    addq    $(early_top_pgt - __START_KERNEL_map), %rax

    /* 設(shè)置 CR4(PAE + PGE) */
    movl    $(X86_CR4_PAE | X86_CR4_PGE), %ecx
    movq    %rcx, %cr4

    /* 切換到新的頁(yè)表 */
    movq    %rax, %cr3

    /* 加載內(nèi)核的 GDT */
    lgdt    early_gdt_descr(%rip)

    /* 清空數(shù)據(jù)段寄存器 */
    xorl    %eax, %eax
    movl    %eax, %ds
    movl    %eax, %ss
    movl    %eax, %es
    movl    %eax, %fs
    movl    %eax, %gs

    /* 設(shè)置 IDT(早期中斷描述符表) */
    pushq   %rsi
    call    early_setup_idt
    popq    %rsi

    /* 設(shè)置 EFER(使能 SYSCALL 等) */
    movl    $MSR_EFER, %ecx
    rdmsr
    btsl    $_EFER_SCE, %eax       /* Enable System Call */
    ...
    wrmsr

    /* 設(shè)置 CR0 */
    movl    $CR0_STATE, %eax
    movq    %rax, %cr0

    /* 清空中斷標(biāo)志 */
    pushq   $0
    popfq

    /* 準(zhǔn)備跳轉(zhuǎn)到 C 代碼 */
    movq    %rsi, %rdi            # real_mode_data 作為參數(shù)

.Ljump_to_C_code:
    xorl    %ebp, %ebp            # 清空幀指針
    movq    initial_code(%rip), %rax    # rax = x86_64_start_kernel
    pushq   $__KERNEL_CS
    pushq   %rax
    lretq                         # 遠(yuǎn)返回,進(jìn)入 x86_64_start_kernel

關(guān)鍵點(diǎn):

  • initial_code 是一個(gè)全局變量,值為 x86_64_start_kernel
  • initial_stack 指向 init_thread_union(這是 PID 0,也就是 swapper/idle 進(jìn)程的棧)
  • lretq 完成一次遠(yuǎn)返回,同時(shí)切換代碼段和跳轉(zhuǎn)到目標(biāo)地址

7. x86 架構(gòu)的 C 語(yǔ)言入口

lretq 把你帶到了 arch/x86/kernel/head64.c

asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
{
    /* 編譯期檢查 */
    BUILD_BUG_ON(MODULES_VADDR < __START_KERNEL_map);
    ...

    /* 初始化 CR4 影子寄存器 */
    cr4_init_shadow();

    /* 清除臨時(shí)頁(yè)表(去掉 identity map) */
    reset_early_page_tables();

    /* 清零 BSS 段 */
    clear_bss();

    /* 復(fù)制 boot_params 到內(nèi)核空間 */
    copy_bootdata(__va(real_mode_data));

    /* 加載 CPU 微碼 */
    load_ucode_bsp();

    /* 設(shè)置正式頁(yè)表的高地址映射 */
    init_top_pgt[511] = early_top_pgt[511];

    x86_64_start_reservations(real_mode_data);
}

void __init x86_64_start_reservations(char *real_mode_data)
{
    if (!boot_params.hdr.version)
        copy_bootdata(__va(real_mode_data));

    x86_early_init_platform_quirks();

    /* 特殊平臺(tái)處理 */
    switch (boot_params.hdr.hardware_subarch) {
    case X86_SUBARCH_INTEL_MID:
        x86_intel_mid_early_setup();
        break;
    default:
        break;
    }

    start_kernel();                 /* ? 進(jìn)入體系無(wú)關(guān)的通用初始化! */
}

從這里開(kāi)始,代碼變得體系無(wú)關(guān)了——不管是 x86、ARM 還是 RISC-V,最終都會(huì)調(diào)用 start_kernel()。

8. 通用內(nèi)核初始化 —— start_kernel()

這是整個(gè)內(nèi)核最著名的函數(shù),位于 init/main.c

asmlinkage __visible void __init start_kernel(void)
{
    char *command_line;
    char *after_dashes;

    /* 設(shè)置 init_task(PID 0)的棧結(jié)束魔數(shù) */
    set_task_stack_end_magic(&init_task);

    smp_setup_processor_id();
    cgroup_init_early();

    /* 關(guān)中斷,初始化期間不允許打擾 */
    local_irq_disable();
    early_boot_irqs_disabled = true;

    boot_cpu_init();
    page_address_init();

    /* 打印 "Linux version 5.15.119 ..." */
    pr_notice("%s", linux_banner);

    early_security_init();

    /* ? 架構(gòu)相關(guān)初始化(內(nèi)存、CPU、ACPI 等) */
    setup_arch(&command_line);

    setup_boot_config();
    setup_command_line(command_line);
    setup_nr_cpu_ids();
    setup_per_cpu_areas();
    smp_prepare_boot_cpu();
    boot_cpu_hotplug_init();

    /* 建立內(nèi)存管理區(qū) */
    build_all_zonelists(NULL);
    page_alloc_init();

    /* 打印命令行 */
    pr_notice("Kernel command line: %s\n", saved_command_line);

    /* 解析早期參數(shù)(如 mem=, console=) */
    parse_early_param();
    parse_args("Booting kernel", static_command_line, ...);

    /* ? 初始化內(nèi)存管理 */
    mm_init();

    ftrace_init();
    sched_init();                   /* ? 初始化調(diào)度器 */
    radix_tree_init();
    workqueue_init_early();
    rcu_init();
    trace_init();
    context_tracking_init();
    early_irq_init();
    init_IRQ();                     /* 初始化中斷 */
    tick_init();
    init_timers();
    timekeeping_init();
    time_init();                    /* 初始化時(shí)間子系統(tǒng) */
    random_init(command_line);
    boot_init_stack_canary();

    /* 開(kāi)中斷 */
    local_irq_enable();
    early_boot_irqs_disabled = false;

    console_init();                 /* 正式初始化控制臺(tái) */

    /* ? 初始化 VFS */
    vfs_caches_init();
    signals_init();
    pagecache_init();
    proc_root_init();               /* 創(chuàng)建 /proc */
    nsfs_init();
    cgroup_init();
    ...
    check_bugs();                   /* 檢查 CPU bug */

    /* ? 調(diào)用 rest_init() */
    arch_call_rest_init();
}

start_kernel() 初始化了內(nèi)核的幾乎所有核心子系統(tǒng)

  • 內(nèi)存管理(MM)
  • 進(jìn)程調(diào)度
  • 中斷、定時(shí)器
  • 文件系統(tǒng)緩存
  • procfs、cgroups

但最后它自己不變成用戶進(jìn)程,而是調(diào)用 rest_init()。

9. rest_init() —— 創(chuàng)建兩個(gè)"祖先進(jìn)程"

源碼位置init/main.c

noinline void __ref rest_init(void)
{
    struct task_struct *tsk;
    int pid;

    rcu_scheduler_starting();

    /*
     * 創(chuàng)建 PID 1:init 進(jìn)程(用戶態(tài)的祖先)
     */
    pid = kernel_thread(kernel_init, NULL, CLONE_FS);

    /* 把 init 固定在 boot CPU 上 */
    rcu_read_lock();
    tsk = find_task_by_pid_ns(pid, &init_pid_ns);
    tsk->flags |= PF_NO_SETAFFINITY;
    set_cpus_allowed_ptr(tsk, cpumask_of(smp_processor_id()));
    rcu_read_unlock();

    /*
     * 創(chuàng)建 PID 2:kthreadd(內(nèi)核線程的祖先)
     */
    pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

    rcu_read_lock();
    kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
    rcu_read_unlock();

    /*
     * 啟用調(diào)度器檢查
     */
    system_state = SYSTEM_SCHEDULING;

    complete(&kthreadd_done);

    /*
     * 當(dāng)前線程(PID 0)變成 idle 進(jìn)程,永遠(yuǎn)執(zhí)行 schedule()
     */
    schedule_preempt_disabled();
    cpu_startup_entry(CPUHP_ONLINE);   /* 進(jìn)入 idle 循環(huán) */
}

這是 Linux 進(jìn)程樹(shù)的起點(diǎn)

PID進(jìn)程作用
0swapper/idle當(dāng)前線程變身而來(lái),沒(méi)事干時(shí)執(zhí)行它
1kernel_init接下來(lái)啟動(dòng)第一個(gè)用戶程序(/sbin/init
2kthreadd專門"收養(yǎng)"內(nèi)核線程,所有內(nèi)核線程的父進(jìn)程

10. kernel_init() —— 啟動(dòng)第一個(gè)用戶程序

源碼位置init/main.c

static int __ref kernel_init(void *unused)
{
    /* 等 kthreadd 準(zhǔn)備好 */
    wait_for_completion(&kthreadd_done);

    /* 加載真正的根文件系統(tǒng) */
    kernel_init_freeable();

    /* 等所有異步 __init 代碼完成 */
    async_synchronize_full();

    /* 釋放 __init 段內(nèi)存(啟動(dòng)完成后這些代碼不再需要) */
    free_initmem();
    mark_readonly();
    pti_finalize();

    /* 系統(tǒng)正式運(yùn)行 */
    system_state = SYSTEM_RUNNING;
    numa_default_policy();
    rcu_end_inkernel_boot();

    /* 按優(yōu)先級(jí)嘗試啟動(dòng)第一個(gè)用戶進(jìn)程 */

    /* 1. initrd 中的 /init */
    if (ramdisk_execute_command) {
        ret = run_init_process(ramdisk_execute_command);
        if (!ret)
            return 0;
    }

    /* 2. 命令行 init=xxx 指定的程序 */
    if (execute_command) {
        ret = run_init_process(execute_command);
        if (!ret)
            return 0;
    }

    /* 3. 編譯時(shí)默認(rèn)的 init */
    if (CONFIG_DEFAULT_INIT[0] != '\0') {
        ret = run_init_process(CONFIG_DEFAULT_INIT);
        if (!ret)
            return 0;
    }

    /* 4. 默認(rèn)路徑 */
    if (!try_to_run_init_process("/sbin/init") ||
        !try_to_run_init_process("/etc/init") ||
        !try_to_run_init_process("/bin/init") ||
        !try_to_run_init_process("/bin/sh"))
        return 0;

    /* 全都失敗 */
    panic("No working init found.  Try passing init= option to kernel.");
}

一旦 run_init_process("/sbin/init") 成功,內(nèi)核就完成了它的啟動(dòng)使命。

從這一刻起,系統(tǒng)控制權(quán)交給了用戶空間。

你看到的 systemd、sysvinit、或 bash,就是從這里開(kāi)始的。

總結(jié):完整啟動(dòng)路線圖

Mermaid 流程圖

ASCII 路線圖(備用)

GRUB 加載 bzImage
    │
    ▼
┌─────────────────────────────────────────────┐
│  arch/x86/boot/header.S                     │  內(nèi)核頭部,存放啟動(dòng)協(xié)議信息
└─────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────┐
│  arch/x86/boot/main.c   main()              │  ?── 16位實(shí)模式
│      └── go_to_protected_mode()             │      收集硬件信息到 boot_params
└─────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────┐
│  arch/x86/boot/pmjump.S                     │  ?── 打開(kāi) CR0.PE
│      protected_mode_jump()                  │      進(jìn)入 32 位保護(hù)模式
└─────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────┐
│  arch/x86/boot/compressed/head_64.S         │  ?── 32→64位切換
│      startup_32 → startup_64                │      建立頁(yè)表,解壓內(nèi)核
└─────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────┐
│  arch/x86/kernel/head_64.S                  │  ?── 真正的內(nèi)核 64 位入口
│      startup_64 → lretq                     │      設(shè)置頁(yè)表/GDT/IDT
└─────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────┐
│  arch/x86/kernel/head64.c                   │  ?── x86 架構(gòu) C 入口
│      x86_64_start_kernel()                  │      清零 BSS,加載微碼
│      └── start_kernel()                     │
└─────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────┐
│  init/main.c   start_kernel()               │  ?── 初始化所有子系統(tǒng)
│      └── arch_call_rest_init()              │      MM、調(diào)度、IRQ、VFS...
│          └── rest_init()                    │
│              ├── kernel_thread(kernel_init) │  PID 1
│              ├── kernel_thread(kthreadd)    │  PID 2
│              └── cpu_startup_entry()        │  PID 0 (idle)
└─────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────┐
│  init/main.c   kernel_init()                │  ?── 啟動(dòng) /sbin/init
│      └── run_init_process()                 │
└─────────────────────────────────────────────┘
    │
    ▼
  用戶空間(systemd / init / bash)

以上就是Linux內(nèi)核啟動(dòng)流程詳解(基于 5.15.119 源碼)的詳細(xì)內(nèi)容,更多關(guān)于Linux內(nèi)核啟動(dòng)流程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • linux命令實(shí)現(xiàn)音頻格式轉(zhuǎn)換和拼接的方法

    linux命令實(shí)現(xiàn)音頻格式轉(zhuǎn)換和拼接的方法

    今天小編就為大家分享一篇linux命令實(shí)現(xiàn)音頻格式轉(zhuǎn)換和拼接的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • Linux(CentOS)上配置 SFTP服務(wù)器

    Linux(CentOS)上配置 SFTP服務(wù)器

    本篇文章主要介紹了Linux(CentOS)上配置 SFTP服務(wù)器。相比傳統(tǒng)的 ftp 服務(wù),SFTP 顯得更加方便、安全,有興趣的朋友可以了解一下。
    2017-03-03
  • linux下掛載VHD等虛擬磁盤文件的方法

    linux下掛載VHD等虛擬磁盤文件的方法

    本篇文章主要介紹了linux下掛載VHD等虛擬磁盤文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • apache性能測(cè)試工具ab使用詳解

    apache性能測(cè)試工具ab使用詳解

    這篇文章主要介紹了apache性能測(cè)試工具ab使用詳解,需要的朋友可以參考下
    2015-01-01
  • centos 7 安裝卸載apache(httpd)服務(wù)的詳細(xì)步驟

    centos 7 安裝卸載apache(httpd)服務(wù)的詳細(xì)步驟

    前面我們已經(jīng)安裝好了mysql,今天安裝httpd,然后試著訪問(wèn)以下,由于博主已經(jīng)安裝過(guò)一次,所以先說(shuō)卸載,再說(shuō)安裝,需要的朋友可以參考下
    2020-07-07
  • Linux 修改 etc/hosts文件詳細(xì)介紹

    Linux 修改 etc/hosts文件詳細(xì)介紹

    這篇文章主要介紹了 Linux 修改 etc/hosts文件詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • centos7切換啟動(dòng)內(nèi)核與切換啟動(dòng)模式的講解

    centos7切換啟動(dòng)內(nèi)核與切換啟動(dòng)模式的講解

    今天小編就為大家分享一篇關(guān)于centos7切換啟動(dòng)內(nèi)核與切換啟動(dòng)模式的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • Linux用戶切換與管理的完整指南

    Linux用戶切換與管理的完整指南

    這篇文章主要介紹了Linux系統(tǒng)中用戶切換與管理的全流程,涵蓋su/sudo權(quán)限操作、SSH遠(yuǎn)程認(rèn)證、會(huì)話管理工具、安全配置策略、狀態(tài)監(jiān)控命令及故障排查方法,重點(diǎn)強(qiáng)調(diào)了權(quán)限控制、安全加固與操作審計(jì)等核心實(shí)踐,需要的朋友可以參考下
    2025-07-07
  • 搭建阿里云ecs服務(wù)器之安裝圖形化界面的方法

    搭建阿里云ecs服務(wù)器之安裝圖形化界面的方法

    這篇文章主要介紹了搭建阿里云ecs服務(wù)器之安裝圖形化界面的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Xshell5連接虛擬機(jī)中的Linux的方法以及失敗原因解決

    Xshell5連接虛擬機(jī)中的Linux的方法以及失敗原因解決

    這篇文章主要介紹了Xshell5連接虛擬機(jī)中的Linux的方法以及失敗原因解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

阜新市| 北宁市| 邮箱| 大庆市| 新绛县| 轮台县| 太保市| 钦州市| 朝阳县| 信丰县| 封开县| 龙里县| 西和县| 巴林左旗| 莱西市| 那坡县| 琼结县| 华坪县| 班玛县| 四子王旗| 横山县| 裕民县| 淅川县| 饶平县| 阳江市| 莱芜市| 鸡西市| 习水县| 濮阳县| 镇巴县| 南宁市| 朝阳市| 苗栗市| 大邑县| 莱州市| 凌海市| 舞钢市| 浮梁县| 阜平县| 芜湖市| 岳普湖县|