主頁 >  其他 > Linux4.1.15內核啟動流程簡單分析

Linux4.1.15內核啟動流程簡單分析

2020-10-08 18:38:45 其他

Linux內核是 Linux 作業系統(OS)的主要組件,也是計算機硬體與其行程之間的核心介面,它負責兩者之間的通信,還要盡可能高效地管理資源,之所以稱為內核,是因為它在作業系統中就像果實硬殼中的種子一樣,并且控制著硬體(無論是電話、筆記本電腦、服務器,還是任何其他型別的計算機)的所有主要功能,
內核到底是什么呢?其實內核就是系統上面的一個檔案而已,這個檔案包含了驅動主機各項硬體的檢測程式與驅動模塊,這個內核檔案通常被放置在/boot/vmlinux-xxx,不過也不一定,因為一部主機上面可以擁有多個核心檔案,只是開機的時候僅僅能選擇一個來加載而已,而內核主要負責記憶體管理、行程管理、設備驅動程式、系統呼叫和安全防護這四項作業,
往期推薦:
史上最全的Linux常用命令匯總(超全面!超詳細!)收藏這一篇就夠了!
史上最全的Uboot常用命令匯總(超全面!超詳細!)收藏這一篇就夠了!
連Linux的開機流程都不了解,怎么好意思說自己是程式員?
在這里插入圖片描述

文章目錄

    • Linux內核入口stext
    • __mmap_switched 函式
    • start_kernel 函式
    • rest_init 函式
    • init 行程

要分析Linux啟動流程,要先編譯一下Linux原始碼,因為很多檔案是需要編譯才會生成的,通過分析以下Linux內核的連接腳本檔案arch/arm/kernel/vmlinux.lds,通過連接腳本可以找到Linux內核的入口為stext,stext定義在arch/arm/kernel/head.S 中 , 因 此 要 分 析 Linux 內 核 的 啟 動 流 程 , 就 得 先 從 文 件
arch/arm/kernel/head.S 的 stext 處開始分析,

Linux內核入口stext

/*
* Kernel startup entry point.
* ---------------------------
*
* This is normally called from the decompressor code. The requirements
* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
* r1 = machine nr, r2 = atags or dtb pointer.
* /

根據代碼的注釋,Linux內核啟動之前要求如下:

  • 關閉MMU(記憶體存盤單元)
  • 關閉D-cache
  • I-Cache無所謂
  • r0=0
  • r1=machine nr(也就是機器ID)
  • r2=atags或者設備樹(dtb)首地址
ENTRY(stext)
 ARM_BE8(setend be )            @ ensure we are in BE8 mode

 THUMB( adr r9, BSYM(1f)    )   @ Kernel is always entered in ARM.
 THUMB( bx  r9      )   @ If this is a Thumb-2 kernel,
 THUMB( .thumb          )   @ switch to Thumb now.
 THUMB(1:           )   

#ifdef CONFIG_ARM_VIRT_EXT
    bl  __hyp_stub_install
#endif
    @ ensure svc mode and all interrupts masked
    safe_svcmode_maskall r9

    mrc p15, 0, r9, c0, c0      @ get processor id
    bl  __lookup_processor_type     @ r5=procinfo r9=cpuid
    movs    r10, r5             @ invalid processor (r5=0)?
 THUMB( it  eq )        @ force fixup-able long branch encoding
    beq __error_p           @ yes, error 'p'
#ifdef CONFIG_ARM_LPAE
    mrc p15, 0, r3, c0, c1, 4       @ read ID_MMFR0
    and r3, r3, #0xf            @ extract VMSA support
    cmp r3, #5              @ long-descriptor translation table format?
 THUMB( it  lo )                @ force fixup-able long branch encoding
    blo __error_lpae            @ only classic page table format
#endif

#ifndef CONFIG_XIP_KERNEL
    adr r3, 2f
    ldmia   r3, {r4, r8}
    sub r4, r3, r4          @ (PHYS_OFFSET - PAGE_OFFSET)
    add r8, r8, r4          @ PHYS_OFFSET
#else
    ldr r8, =PLAT_PHYS_OFFSET       @ always constant in this case
#endif

    /*
     * r1 = machine no, r2 = atags or dtb,
     * r8 = phys_offset, r9 = cpuid, r10 = procinfo
     */
    bl  __vet_atags
#ifdef CONFIG_SMP_ON_UP
    bl  __fixup_smp
#endif
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
    bl  __fixup_pv_table
#endif
    bl  __create_page_tables

    /*
     * The following calls CPU specific code in a position independent
     * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
     * xxx_proc_info structure selected by __lookup_processor_type
     * above.  On return, the CPU will be ready for the MMU to be
     * turned on, and r0 will hold the CPU control register value.
     */
    ldr r13, =__mmap_switched       @ address to jump to after
                        @ mmu has been enabled
	adr lr, BSYM(1f)            @ return (PIC) address
    mov r8, r4              @ set TTBR1 to swapper_pg_dir
    ldr r12, [r10, #PROCINFO_INITFUNC]
    add r12, r12, r10
    ret r12
1:  b   __enable_mmu
ENDPROC(stext)

通過分析上述代碼,第12行,呼叫safe_svcmode_maskall 確保 CPU 處于 SVC 模式,并且關閉了所有的中斷, 關閉后讀取處理器的ID,ID值保存在r9暫存器中,然后呼叫__lookup_processor_type 檢查當前系統是否支持此 CPU,如果支持的就獲 取 procinfo 信 息 , procinfo 是 proc_info_list 類 型 的 結 構 體 ,proc_info_list 在 文 件arch/arm/include/asm/procinfo.h 中的定義如下:

struct proc_info_list {
	unsigned int cpu_val;
	unsigned int cpu_mask;
	unsigned long __cpu_mm_mmu_flags; /* used by head.S */
	unsigned long __cpu_io_mmu_flags; /* used by head.S */
	unsigned long __cpu_flush; /* used by head.S */
	const char *arch_name;
	const char *elf_name;
	unsigned int elf_hwcap;
	const char *cpu_name;
	struct processor *proc;
	struct cpu_tlb_fns *tlb;
	struct cpu_user_fns *user;
	struct cpu_cache_fns *cache;
};

Linux內核將每種處理器都抽象為一個proc_info_list的結構體,每種處理器對應一個procinfo,因此可以通過處理器ID來找到對應的procinfo結構, __lookup_processor_type 函式找到對應處理器的 procinfo 以后會將其保存到 r5 暫存器中,
第41行代碼中,呼叫函式__vet_atags 驗證 atags 或設備樹(dtb)的合法性,第48行,呼叫函式__create_page_tables 創建頁表,第57行,將函式__mmap_switched 的地址保存到 r13 暫存器中, __mmap_switched 定義在檔案 arch/arm/kernel/head-common.S__mmap_switched 最侄訓呼叫 start_kernel 函式,第 64 行 , 調 用 __enable_mmu 函 數 使 能 MMU , __enable_mmu 定 義 在 文 件arch/arm/kernel/head.S 中, __enable_mmu 最侄訓通過呼叫__turn_mmu_on 來打開 MMU,__turn_mmu_on 最后會執行 r13 里面保存的__mmap_switched 函式,

__mmap_switched 函式

__mmap_switched 函式定義在檔案 arch/arm/kernel/head-common.S 中,函式代碼如下:

__mmap_switched:
	 adr r3, __mmap_switched_data
	
	 ldmia r3!, {r4, r5, r6, r7}
	 cmp r4, r5 @ Copy data segment if needed
	 1: cmpne r5, r6
	 ldrne fp, [r4], #4
	 strne fp, [r5], #4
	 bne 1b
	
	 mov fp, #0 @ Clear BSS (and zero fp)
	 1: cmp r6, r7
	 strcc fp, [r6],#4
	 bcc 1b
	
	 ARM( ldmia r3, {r4, r5, r6, r7, sp})
	 THUMB( ldmia r3, {r4, r5, r6, r7} )
	 THUMB( ldr sp, [r3, #16] )
	 str r9, [r4] @ Save processor ID
	 str r1, [r5] @ Save machine type
	 str r2, [r6] @ Save atags pointer
	 cmp r7, #0
	 strne r0, [r7] @ Save control register values
	 b start_kernel
	 ENDPROC(__mmap_switched)

該函式最終通過呼叫start_kernel來啟動Linux內核

start_kernel 函式

start_kernel通過呼叫眾多的子函式來完成Linux啟動之前的一些初始化作業,由于start_kernel函式里面呼叫的函式太多,而且這些子函式又很復雜,我們只是簡單的了解一下Linux內核的啟動流程,只需要簡單了解一些比較重要的函式就可以啦!

asmlinkage __visible void __init start_kernel(void)
{
	char *command_line;
	char *after_dashes;
	lockdep_init(); /* lockdep 是死鎖檢測模塊,此函式會初始化
					* 兩個 hash 表,此函式要求盡可能早的執行!
					*/
	set_task_stack_end_magic(&init_task);/* 設定任務堆疊結束魔術數,
										*用于堆疊溢位檢測
										*/
	smp_setup_processor_id(); /* 跟 SMP 有關(多核處理器),設定處理器 ID,
								* 有很多資料說 ARM 架構下此函式為空函式,那是因
								* 為他們用的老版本 Linux,而那時候 ARM 還沒有多
								* 核處理器,
								*/
	debug_objects_early_init(); /* 做一些和 debug 有關的初始化 */
	boot_init_stack_canary(); /* 堆疊溢位檢測初始化 */
	cgroup_init_early(); /* cgroup 初始化, cgroup 用于控制 Linux 系統資源*/
	local_irq_disable(); /* 關閉當前 CPU 中斷 */
	early_boot_irqs_disabled = true;
	/*
	* 中斷關閉期間做一些重要的操作,然后打開中斷
	*/
	boot_cpu_init(); /* 跟 CPU 有關的初始化 */
	page_address_init(); /* 頁地址相關的初始化 */
	pr_notice("%s", linux_banner);/* 列印 Linux 版本號、編譯時間等資訊 */
	setup_arch(&command_line); /* 架構相關的初始化,此函式會決議傳遞進來的
								* ATAGS 或者設備樹(DTB)檔案,會根據設備樹里面
								* 的 model 和 compatible 這兩個屬性值來查找
								* Linux 是否支持這個單板,此函式也會獲取設備樹
								* 中 chosen 節點下的 bootargs 屬性值來得到命令
								* 行引數,也就是 uboot 中的 bootargs 環境變數的
								* 值,獲取到的命令列引數會保存到
								*command_line 中,
								*/
	mm_init_cpumask(&init_mm); /* 看名字,應該是和記憶體有關的初始化 */
	setup_command_line(command_line); /* 好像是存盤命令列引數 */
	setup_nr_cpu_ids(); /* 如果只是 SMP(多核 CPU)的話,此函式用于獲取
							* CPU 核心數量, CPU 數量保存在變數
							* nr_cpu_ids 中,
						*/
	setup_per_cpu_areas(); /* 在 SMP 系統中有用,設定每個 CPU 的 per-cpu 資料 */
	smp_prepare_boot_cpu();
	build_all_zonelists(NULL, NULL); /* 建立系統記憶體頁區(zone)鏈表 */
	page_alloc_init(); /* 處理用于熱插拔 CPU 的頁 */
	/* 列印命令列資訊 */
	pr_notice("Kernel command line: %s\n", boot_command_line);
	parse_early_param(); /* 決議命令列中的 console 引數 */
	after_dashes = parse_args("Booting kernel",
	static_command_line, __start___param,
	__stop___param - __start___param,
	-1, -1, &unknown_bootoption);
	if (!IS_ERR_OR_NULL(after_dashes))
		parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,set_init_arg);
	jump_label_init();
	setup_log_buf(0); /* 設定 log 使用的緩沖區*/
	pidhash_init(); /* 構建 PID 哈希表, Linux 中每個行程都有一個 ID,
					* 這個 ID 叫做 PID,通過構建哈希表可以快速搜索行程
					* 資訊結構體,
					*/
	vfs_caches_init_early(); /* 預先初始化 vfs(虛擬檔案系統)的目錄項和
							* 索引節點快取
							*/
	sort_main_extable(); /* 定義內核例外串列 */
	trap_init(); /* 完成對系統保留中斷向量的初始化 */
	mm_init(); /* 記憶體管理初始化 */
	sched_init(); /* 初始化調度器,主要是初始化一些結構體 */
	preempt_disable(); /* 關閉優先級搶占 */
	if (WARN(!irqs_disabled(), /* 檢查中斷是否關閉,如果沒有的話就關閉中斷 */
	"Interrupts were enabled *very* early, fixing it\n"))
		local_irq_disable();
	idr_init_cache(); /* IDR 初始化, IDR 是 Linux 內核的整數管理機
						* 制,也就是將一個整數 ID 與一個指標關聯起來,
					 */
	rcu_init(); /* 初始化 RCU, RCU 全稱為 Read Copy Update(讀-拷貝修改) */
	trace_init(); /* 跟蹤除錯相關初始化 */
	context_tracking_init();
	radix_tree_init(); /* 基數樹相關資料結構初始化 */
	early_irq_init(); /* 初始中斷相關初始化,主要是注冊 irq_desc 結構體變
						* 量,因為 Linux 內核使用 irq_desc 來描述一個中斷,
					*/
	init_IRQ(); /* 中斷初始化 */
	tick_init(); /* tick 初始化 */
	rcu_init_nohz();
	init_timers(); /* 初始化定時器 */
	hrtimers_init(); /* 初始化高精度定時器 */
	softirq_init(); /* 軟中斷初始化 */
	timekeeping_init();
	time_init(); /* 初始化系統時間 */
	sched_clock_postinit();
	perf_event_init();
	profile_init();
	call_function_init();
	WARN(!irqs_disabled(), "Interrupts were enabled early\n");
	early_boot_irqs_disabled = false;
	local_irq_enable(); /* 使能中斷 */
	kmem_cache_init_late(); /* slab 初始化, slab 是 Linux 記憶體分配器 */
	console_init(); /* 初始化控制臺,之前 printk 列印的資訊都存放
					* 緩沖區中,并沒有列印出來,只有呼叫此函式
					* 初始化控制臺以后才能在控制臺上列印資訊,
					*/
	if (panic_later)
		panic("Too many boot %s vars at `%s'", panic_later,panic_param);
	lockdep_info();/* 如果定義了宏 CONFIG_LOCKDEP,那么此函式列印一些資訊, */
	locking_selftest() /* 鎖自測 */
	......
	page_ext_init();
	debug_objects_mem_init();
	kmemleak_init(); /* kmemleak 初始化, kmemleak 用于檢查記憶體泄漏 */
	setup_per_cpu_pageset();
	numa_policy_init();
	if (late_time_init)
		late_time_init();
	sched_clock_init();
	calibrate_delay(); /* 測定 BogoMIPS 值,可以通過 BogoMIPS 來判斷 CPU 的性能
						* BogoMIPS 設定越大,說明 CPU 性能越好,
						*/
	pidmap_init(); /* PID 位圖初始化 */
	anon_vma_init(); /* 生成 anon_vma slab 快取 */
	acpi_early_init();
	......
	thread_info_cache_init();
	cred_init(); /* 為物件的每個用于賦予資格(憑證) */
	fork_init(); /* 初始化一些結構體以使用 fork 函式 */
	proc_caches_init(); /* 給各種資源管理結構分配快取 */
	buffer_init(); /* 初始化緩沖快取 */
	key_init(); /* 初始化密鑰 */
	security_init(); /* 安全相關初始化 */
	dbg_late_init();
	vfs_caches_init(totalram_pages); /* 為 VFS 創建快取 */
	signals_init(); /* 初始化信號 */
	page_writeback_init(); /* 頁回寫初始化 */
	proc_root_init(); /* 注冊并掛載 proc 檔案系統 */
	nsfs_init();
	cpuset_init(); /* 初始化 cpuset, cpuset 是將 CPU 和記憶體資源以邏輯性
	* 和層次性集成的一種機制,是 cgroup 使用的子系統之一
	*/
	cgroup_init(); /* 初始化 cgroup */
	taskstats_init_early(); /* 行程狀態初始化 */
	delayacct_init();
	check_bugs(); /* 檢查寫緩沖一致性 */
	acpi_subsystem_init();
	sfi_init_late();
	if (efi_enabled(EFI_RUNTIME_SERVICES)) {
		efi_late_init();
		efi_free_boot_services();
	}
	ftrace_init();
	rest_init(); /* rest_init 函式 */
}

start_kernel 里面呼叫了大量的函式,每一個函式都是一個龐大的知識點,如果想要學習Linux 內核,那么這些函式就需要去詳細的研究,本篇文章只是簡單介紹 Linux內核啟動流程,因此不會去講太多關于 Linux 內核的知識, start_kernel 函式最后呼叫了 rest_init

rest_init 函式

rest_init 函式定義在檔案 init/main.c 中,函式內容如下:

static noinline void __init_refok rest_init(void)
{
	 int pid;	
	 rcu_scheduler_starting();
	 smpboot_thread_init();
	 /*
	 * We need to spawn init first so that it obtains pid 1, however
	 * the init task will end up wanting to create kthreads, which,
	 * if we schedule it before we create kthreadd, will OOPS.
	 */
	 kernel_thread(kernel_init, NULL, CLONE_FS);
	 numa_default_policy();
	 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();
	 complete(&kthreadd_done);
	/*
	 * The boot idle thread must execute schedule()
	 * at least once to get things moving:
	 */
	 init_idle_bootup_task(current);
	 schedule_preempt_disabled();
	 /* Call into cpu_idle with preempt disabled */
	 cpu_startup_entry(CPUHP_ONLINE);
 }

在第三行,通過呼叫函式rcu_scheduler_starting,來啟動 RCU 鎖調度器,

第十行,呼叫函式 kernel_thread 創建 kernel_init 執行緒,也就是大名鼎鼎的 init 內核行程,init 行程的 PID 為 1, init 行程一開始是內核行程(也就是運行在內核態),后面 init 行程會在根檔案系統中查找名為“init”這個程式,這個“init”程式處于用戶態,通過運行這個“init”程式, init 行程就會實作從內核態到用戶態的轉變,

第十二行,呼叫函式 kernel_thread 創建 kthreadd 內核行程,此內核行程的 PID 為 2,kthreadd行程負責所有內核行程的調度和管理

第二十五行,呼叫函式cpu_startup_entry 來進入 idle 行程, cpu_startup_entry 會呼叫cpu_idle_loop, cpu_idle_loop 是個 while 回圈,也就是 idle 行程代碼, idle 行程的 PID 為 0idle行程叫做空閑行程,如果學過 FreeRTOS 或者 UCOS 的話應該聽說過空閑任務, idle 空閑行程就和空閑任務一樣,當 CPU 沒有事情做的時候就在 idle 空閑行程里面“瞎逛游”,反正就是給CPU 找點事做,當其他行程要作業的時候就會搶占 idle 行程,從而奪取 CPU 使用權,其實大家應該可以看到 idle 行程并沒有使用 kernel_thread 或者 fork 函式來創建,因為它是有主行程演變而來的,

在 Linux 終端中輸入ps -A就可以列印出當前系統中的所有行程,其中就能看到 init 進
程和 kthreadd 行程:
在這里插入圖片描述
從圖中可以看出, init 行程的 PID 為 1, kthreadd 行程的 PID 為 2,之所以圖中沒有顯示 PID 為 0 的 idle 行程,那是因為 idle 行程是內核行程

init 行程

kernel_init 函式就是 init 行程具體做的作業,定義在檔案 init/main.c 中,函式內容如下:

static int __ref kernel_init(void *unused)
{
	int ret;
	
	 kernel_init_freeable(); /* init 行程的一些其他初始化作業 */
	 /* need to finish all async __init code before freeing the
	memory */
	 async_synchronize_full(); /* 等待所有的異步呼叫執行完成 */
	 free_initmem(); /* 釋放 init 段記憶體 */
	 mark_rodata_ro();
	 system_state = SYSTEM_RUNNING; /* 標記系統正在運行 */
	 numa_default_policy();
	
	 flush_delayed_fput();
	
	 if (ramdisk_execute_command) {
		 ret = run_init_process(ramdisk_execute_command);
		 if (!ret)
		 return 0;
		 pr_err("Failed to execute %s (error %d)\n",
		 ramdisk_execute_command, ret);
	}

	 /*
	 * We try each of these until one succeeds.
	 *
	 * The Bourne shell can be used instead of init if we are
	 * trying to recover a really broken machine.
	 */
	 if (execute_command) {
		 ret = run_init_process(execute_command);
		 if (!ret)
		 	return 0;
		 panic("Requested init %s failed (error %d).",
		 execute_command, ret);
	 }
	 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. "
	 "See Linux Documentation/init.txt for guidance.");
 }

第五行,kernel_init_freeable 函式用于完成 init 行程的一些其他初始化作業,

第十三行,ramdisk_execute_command 是一個全域的 char 指標變數,此變數值為“/init”,
也就是根目錄下的 init 程式, ramdisk_execute_command 也可以通過 uboot 傳遞,在 bootargs 中使用“rdinit=xxx”即可, xxx 為具體的 init 程式名字,

第十六行,如果存在“/init”程式的話就通過函式 run_init_process 來運行此程式,

第三十九行,如果 ramdisk_execute_command 為空的話就看 execute_command 是否為空,反正不管如何一定要在根檔案系統中找到一個可運行的 init 程式, execute_command 的值是通過uboot 傳遞,在 bootargs 中使用“init=xxxx”就可以了,比如“init=/linuxrc”表示根檔案系統中的 linuxrc 就是要執行的用戶空間 init 程式,

第四十六~四十九行,如果 ramdisk_execute_command 和 execute_command 都為空,那么就依次查找“/sbin/init”、“/etc/init”、“/bin/init”和“/bin/sh”,這四個相當于備用 init 程式,如果這四個也不存在,那么 Linux 啟動失敗!

第五十二行,如果以上步驟都沒有找到用戶空間的 init 程式,那么就提示錯誤發生!

Linux 內核最終是需要和根檔案系統打交道的,需要掛載根檔案系統,并且執行根檔案系統中的 init 程式,以此來進去用戶態,這里就正式引出了根檔案系統,根檔案系統也是我們系統移植的最后一片拼圖, Linux 移植三巨頭: uboot、 Linux kernel、 rootfs(根檔案系統)

注意:
由于作者技術能力有限,文中大部分內容借鑒正點原子官方提供的 I.MX6ULL嵌入式Linux驅動開發指南,如果出現些許理解錯誤希望大家理解, 本文著作權歸萬里羊所有,有需要轉載請宣告文章鏈接和出處

不積小流無以成江河,不積跬步無以至千里,而我想要成為萬里羊,就必須堅持學習來獲取更多知識,用知識來改變命運,用博客見證成長,用行動證明我在努力,
如果我的博客對你有幫助、如果你喜歡我的博客內容,記得“點贊” “評論” “收藏”一鍵三連哦!聽說點贊的人運氣不會太差,每一天都會元氣滿滿呦!如果實在要白嫖的話,那祝你開心每一天,歡迎常來我博客看看,
在這里插入圖片描述

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

標籤:AI

上一篇:PyCharm安裝PyQt5及其工具(Qt Designer、PyUIC、PyRcc)詳細教程

下一篇:Github 與 Git,新手初次接觸的尷尬歷程

標籤雲
其他(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)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more