1. 程式人生 > >2015版uboot的啟動過程及網絡卡驅動結構分析

2015版uboot的啟動過程及網絡卡驅動結構分析

啟動流程和上篇博文介紹的rtems類似

首先是start.s:

在這裡選擇arm的arm7作為例子分析,程式碼:/arch/arm/cpu/armv7/start.s

/*
 * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
 *
 * Copyright (c) 2004	Texas Instruments <[email protected]>
 *
 * Copyright (c) 2001	Marius Gröger <[email protected]>
 * Copyright (c) 2002	Alex Züpke <
[email protected]
> * Copyright (c) 2002 Gary Jennejohn <[email protected]> * Copyright (c) 2003 Richard Woodruff <[email protected]> * Copyright (c) 2003 Kshitij <[email protected]> * Copyright (c) 2006-2008 Syed Mohammed Khasim <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ #include <asm-offsets.h> #include <config.h> #include <asm/system.h> #include <linux/linkage.h> /************************************************************************* * * Startup Code (reset vector) //這是真正的啟動程式碼 * * Do important init only if we don't start from memory! * Setup memory and board specific bits prior to relocation. * Relocate armboot to ram. Setup stack. * *************************************************************************/ .globl reset .globl save_boot_params_ret reset: /* Allow the board to save important registers */ b save_boot_params save_boot_params_ret: /* * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, * except if in HYP mode already */ mrs r0, cpsr and r1, r0, #0x1f @ mask mode bits teq r1, #0x1a @ test for HYP mode bicne r0, r0, #0x1f @ clear all mode bits orrne r0, r0, #0x13 @ set SVC mode orr r0, r0, #0xc0 @ disable FIQ and IRQ msr cpsr,r0 /* * Setup vector: * (OMAP4 spl TEXT_BASE is not 32 byte aligned. * Continue to use ROM code vector only in OMAP4 spl) */ #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register bic r0, #CR_V @ V = 0 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register /* Set vector address in CP15 VBAR register */ ldr r0, =_start mcr p15, 0, r0, c12, c0, 0 @Set VBAR #endif /* the mask ROM code should have PLL and others stable */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_cp15 bl cpu_init_crit #endif bl _main /*------------------------------------------------------------------------------*/ ENTRY(c_runtime_cpu_setup) /* * If I-cache is enabled invalidate it */ #ifndef CONFIG_SYS_ICACHE_OFF mcr p15, 0, r0, c7, c5, 0 @ invalidate icache mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB #endif bx lr ENDPROC(c_runtime_cpu_setup) /************************************************************************* * * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) * __attribute__((weak)); * * Stack pointer is not yet initialized at this moment * Don't save anything to stack even if compiled with -O0 * *************************************************************************/ ENTRY(save_boot_params) b save_boot_params_ret @ back to my caller ENDPROC(save_boot_params) .weak save_boot_params /************************************************************************* * * cpu_init_cp15 * * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless * CONFIG_SYS_ICACHE_OFF is defined. * *************************************************************************/ ENTRY(cpu_init_cp15) /* * Invalidate L1 I/D */ mov r0, #0 @ set up for MCR mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs mcr p15, 0, r0, c7, c5, 0 @ invalidate icache mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array mcr p15, 0, r0, c7, c10, 4 @ DSB mcr p15, 0, r0, c7, c5, 4 @ ISB /* * disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002000 @ clear bits 13 (--V-) bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB #ifdef CONFIG_SYS_ICACHE_OFF bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache #else orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache #endif mcr p15, 0, r0, c1, c0, 0 #ifdef CONFIG_ARM_ERRATA_716044 mrc p15, 0, r0, c1, c0, 0 @ read system control register orr r0, r0, #1 << 11 @ set bit #11 mcr p15, 0, r0, c1, c0, 0 @ write system control register #endif #if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072)) mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 4 @ set bit #4 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register #endif #ifdef CONFIG_ARM_ERRATA_743622 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 6 @ set bit #6 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register #endif #ifdef CONFIG_ARM_ERRATA_751472 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 11 @ set bit #11 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register #endif #ifdef CONFIG_ARM_ERRATA_761320 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 21 @ set bit #21 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register #endif mov r5, lr @ Store my Caller mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) mov r3, r1, lsr #20 @ get variant field and r3, r3, #0xf @ r3 has CPU variant and r4, r1, #0xf @ r4 has CPU revision mov r2, r3, lsl #4 @ shift variant field for combined value orr r2, r4, r2 @ r2 has combined CPU variant + revision #ifdef CONFIG_ARM_ERRATA_798870 cmp r2, #0x30 @ Applies to lower than R3p0 bge skip_errata_798870 @ skip if not affected rev cmp r2, #0x20 @ Applies to including and above R2p0 blt skip_errata_798870 @ skip if not affected rev mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg orr r0, r0, #1 << 7 @ Enable hazard-detect timeout push {r1-r5} @ Save the cpu info registers bl v7_arch_cp15_set_l2aux_ctrl isb @ Recommended ISB after l2actlr update pop {r1-r5} @ Restore the cpu info - fall through skip_errata_798870: #endif #ifdef CONFIG_ARM_ERRATA_801819 cmp r2, #0x24 @ Applies to lt including R2p4 bgt skip_errata_801819 @ skip if not affected rev cmp r2, #0x20 @ Applies to including and above R2p0 blt skip_errata_801819 @ skip if not affected rev mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg and r0, r0, #1 << 3 @ check REVIDR[3] cmp r0, #1 << 3 beq skip_errata_801819 @ skip erratum if REVIDR[3] is set mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate @ lines allocate in the L1 or L2 cache. orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate @ lines allocate in the L1 cache. push {r1-r5} @ Save the cpu info registers bl v7_arch_cp15_set_acr pop {r1-r5} @ Restore the cpu info - fall through skip_errata_801819: #endif #ifdef CONFIG_ARM_ERRATA_454179 cmp r2, #0x21 @ Only on < r2p1 bge skip_errata_454179 mrc p15, 0, r0, c1, c0, 1 @ Read ACR orr r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits push {r1-r5} @ Save the cpu info registers bl v7_arch_cp15_set_acr pop {r1-r5} @ Restore the cpu info - fall through skip_errata_454179: #endif #ifdef CONFIG_ARM_ERRATA_430973 cmp r2, #0x21 @ Only on < r2p1 bge skip_errata_430973 mrc p15, 0, r0, c1, c0, 1 @ Read ACR orr r0, r0, #(0x1 << 6) @ Set IBE bit push {r1-r5} @ Save the cpu info registers bl v7_arch_cp15_set_acr pop {r1-r5} @ Restore the cpu info - fall through skip_errata_430973: #endif #ifdef CONFIG_ARM_ERRATA_621766 cmp r2, #0x21 @ Only on < r2p1 bge skip_errata_621766 mrc p15, 0, r0, c1, c0, 1 @ Read ACR orr r0, r0, #(0x1 << 5) @ Set L1NEON bit push {r1-r5} @ Save the cpu info registers bl v7_arch_cp15_set_acr pop {r1-r5} @ Restore the cpu info - fall through skip_errata_621766: #endif mov pc, r5 @ back to my caller ENDPROC(cpu_init_cp15) #ifndef CONFIG_SKIP_LOWLEVEL_INIT /************************************************************************* * * CPU_init_critical registers * * setup important registers * setup memory timing * *************************************************************************/ ENTRY(cpu_init_crit) /* * Jump to board specific initialization... * The Mask ROM will have already initialized * basic memory. Go here to bump up clock rate and handle * wake up conditions. */ b lowlevel_init @ go setup pll,mux,memory ENDPROC(cpu_init_crit) #endif

這部分主要是彙編編寫。

然後進入main_loop函式中:

檔案:common/main.c

void main_loop(void)
{
	const char *s;

	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

#ifndef CONFIG_SYS_GENERIC_BOARD
	puts("Warning: Your board does not use generic board. Please read\n");
	puts("doc/README.generic-board and take action. Boards not\n");
	puts("upgraded by the late 2014 may break or be removed.\n");
#endif

	modem_init();
#ifdef CONFIG_VERSION_VARIABLE
	setenv("ver", version_string);  /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */

	cli_init();

	run_preboot_environment_command();

#if defined(CONFIG_UPDATE_TFTP)
	update_tftp(0UL, NULL, NULL);
#endif /* CONFIG_UPDATE_TFTP */

	s = bootdelay_process();
	if (cli_process_fdt(&s))
		cli_secure_boot_cmd(s);

	autoboot_command(s);

	cli_loop();
}


其中bootdelay_process函式是為了獲取各種bootcmd環境變數:

檔案:autoboot.c

const char *bootdelay_process(void)
{
	char *s;
	int bootdelay;
#ifdef CONFIG_BOOTCOUNT_LIMIT
	unsigned long bootcount = 0;
	unsigned long bootlimit = 0;
#endif /* CONFIG_BOOTCOUNT_LIMIT */

#ifdef CONFIG_BOOTCOUNT_LIMIT
	bootcount = bootcount_load();
	bootcount++;
	bootcount_store(bootcount);
	setenv_ulong("bootcount", bootcount);
	bootlimit = getenv_ulong("bootlimit", 10, 0);
#endif /* CONFIG_BOOTCOUNT_LIMIT */

	s = getenv("bootdelay");
	bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

#ifdef CONFIG_OF_CONTROL
	bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
			bootdelay);
#endif

	debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);

#if defined(CONFIG_MENU_SHOW)
	bootdelay = menu_show(bootdelay);
#endif
	bootretry_init_cmd_timeout();

#ifdef CONFIG_POST
	if (gd->flags & GD_FLG_POSTFAIL) {
		s = getenv("failbootcmd");
	} else
#endif /* CONFIG_POST */
#ifdef CONFIG_BOOTCOUNT_LIMIT
	if (bootlimit && (bootcount > bootlimit)) {
		printf("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
		       (unsigned)bootlimit);
		s = getenv("altbootcmd");
	} else
#endif /* CONFIG_BOOTCOUNT_LIMIT */
		s = getenv("bootcmd");

	process_fdt_options(gd->fdt_blob);
	stored_bootdelay = bootdelay;

	return s;
}

該函式首先是獲取了bootdelay,將其作為按鍵觸發時間限制,這個待會討論。函式最後,s是獲得了bootcmd變數的資料,然後將其返回。

返回到main_loop函式。接下去執行autoboot_command函式:

檔案:autoboot.c

void autoboot_command(const char *s)
{
	debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");

	if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) {
#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
		int prev = disable_ctrlc(1);	/* disable Control C checking */
#endif

		run_command_list(s, -1, 0);

#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
		disable_ctrlc(prev);	/* restore Control C checking */
#endif
	}

#ifdef CONFIG_MENUKEY
	if (menukey == CONFIG_MENUKEY) {
		s = getenv("menucmd");
		if (s)
			run_command_list(s, -1, 0);
	}
#endif /* CONFIG_MENUKEY */
}

該函式首先判斷bootdelay,利用一個判斷式:if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay))
該判斷式中呼叫了abortboot函式:
static int abortboot(int bootdelay)
{
#ifdef CONFIG_AUTOBOOT_KEYED
	return abortboot_keyed(bootdelay);
#else
	return abortboot_normal(bootdelay);
#endif
}

這裡沒有定義CONFIG_AUTOBOOT_KEYED,這個巨集定義的意思是定義了指定按鍵,我們是按任意鍵停止boot,所以沒有定義,執行abortboot_normal函式。

abortboot_normal:

static int abortboot_normal(int bootdelay)
{
	int abort = 0;
	unsigned long ts;

#ifdef CONFIG_MENUPROMPT
	printf(CONFIG_MENUPROMPT);
#else
	if (bootdelay >= 0)
		printf("Hit any key to stop autoboot: %2d ", bootdelay);
#endif

#if defined CONFIG_ZERO_BOOTDELAY_CHECK
	/*
	 * Check if key already pressed
	 * Don't check if bootdelay < 0
	 */
	if (bootdelay >= 0) {
		if (tstc()) {	/* we got a key press	*/
			(void) getc();  /* consume input	*/
			puts("\b\b\b 0");
			abort = 1;	/* don't auto boot	*/
		}
	}
#endif

	while ((bootdelay > 0) && (!abort)) {
		--bootdelay;
		/* delay 1000 ms */
		ts = get_timer(0);
		do {
			if (tstc()) {	/* we got a key press	*/
				abort  = 1;	/* don't auto boot	*/
				bootdelay = 0;	/* no more delay	*/
# ifdef CONFIG_MENUKEY
				menukey = getc();
# else
				(void) getc();  /* consume input	*/
# endif
				break;
			}
			udelay(10000);
		} while (!abort && get_timer(ts) < 1000);

		printf("\b\b\b%2d ", bootdelay);
	}

	putc('\n');

#ifdef CONFIG_SILENT_CONSOLE
	if (abort)
		gd->flags &= ~GD_FLG_SILENT;
#endif

	return abort;
}

這裡判斷如果bootdelay是大於0的,也就是定義了bootdelay時間,那麼列印Hit any key to stop autoboot:,提示敲擊任意鍵即可終止,然後函式開始檢測有無按鍵按下:

if (tstc()) {	/* we got a key press	*/ 如果有按鍵按下
				abort  = 1;	/* don't auto boot	*/ 將abort置為1
				bootdelay = 0;                      //將bootdelay設定為0

最後函式返回abort。

然後回到autoboot_command函式的判斷式中,如果按鍵沒有按下,也就是abort函式返回0,判斷式條件成立,將禁用ctrl+c按鍵,並呼叫run_command_list函式,該函式執行從環境變數讀取的bootcmd的值,也就是s。

該函式在cli.c檔案中:

int run_command_list(const char *cmd, int len, int flag)
{
	int need_buff = 1;
	char *buff = (char *)cmd;	/* cast away const */
	int rcode = 0;

	if (len == -1) {
		len = strlen(cmd);
#ifdef CONFIG_SYS_HUSH_PARSER
		/* hush will never change our string */
		need_buff = 0;
#else
		/* the built-in parser will change our string if it sees \n */
		need_buff = strchr(cmd, '\n') != NULL;
#endif
	}
	if (need_buff) {
		buff = malloc(len + 1);
		if (!buff)
			return 1;
		memcpy(buff, cmd, len);
		buff[len] = '\0';
	}
#ifdef CONFIG_SYS_HUSH_PARSER
	rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON);
#else
	/*
	 * This function will overwrite any \n it sees with a \0, which
	 * is why it can't work with a const char *. Here we are making
	 * using of internal knowledge of this function, to avoid always
	 * doing a malloc() which is actually required only in a case that
	 * is pretty rare.
	 */
	rcode = cli_simple_run_command_list(buff, flag);
	if (need_buff)
		free(buff);
#endif

	return rcode;
}

該函式通過parse_string_outer函式呼叫了bush_shell的命令直譯器parse_stream_outer函式來解釋bootcmd的命令,而環境變數bootcmd的啟動命令用來設定linux必要的啟動環境,然後載入和啟動核心。

回到上面,如果有按鍵進行干預,那麼判讀式不成立,跳出執行menucmd命令:

#ifdef CONFIG_MENUKEY
	if (menukey == CONFIG_MENUKEY) {
		s = getenv("menucmd");
		if (s)
			run_command_list(s, -1, 0);
	}

s = getenv("menucmd");是用來獲取在uboot命令列下輸入的命令,menucmd就是儲存命令的環境變數。然後同樣執行run_command_list進行命令解釋,然後跳回到main_loop函式,執行最後的cli_loop函式,也就是進入了uboot命令列模式。

以上就是uboot的啟動過程的分析。

接下來簡單說說uboot對於網絡卡驅動的結構:

首先是最底層的驅動檔案,在這裡選擇cpsw.c驅動檔案進行分析,這是ti公司處理器所獨創的一種驅動方式:

檔案:driver/net/cpsw.c

這裡麵包含了cpsw的傳送,接受,初始化,註冊等。

int cpsw_register(struct cpsw_platform_data *data)
{
	struct cpsw_priv	*priv;
	struct cpsw_slave	*slave;
	void			*regs = (void *)data->cpsw_base;
	struct eth_device	*dev;

	dev = calloc(sizeof(*dev), 1);
	if (!dev)
		return -ENOMEM;

	priv = calloc(sizeof(*priv), 1);
	if (!priv) {
		free(dev);
		return -ENOMEM;
	}

	priv->data = *data;
	priv->dev = dev;

	priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves);
	if (!priv->slaves) {
		free(dev);
		free(priv);
		return -ENOMEM;
	}

	priv->host_port		= data->host_port_num;
	priv->regs		= regs;
	priv->host_port_regs	= regs + data->host_port_reg_ofs;
	priv->dma_regs		= regs + data->cpdma_reg_ofs;
	priv->ale_regs		= regs + data->ale_reg_ofs;
	priv->descs		= (void *)regs + data->bd_ram_ofs;

	int idx = 0;

	for_each_slave(slave, priv) {
		cpsw_slave_setup(slave, idx, priv);
		idx = idx + 1;
	}

	strcpy(dev->name, "cpsw");
	dev->iobase	= 0;
	dev->init	= cpsw_init;
	dev->halt	= cpsw_halt;
	dev->send	= cpsw_send;
	dev->recv	= cpsw_recv;
	dev->priv	= priv;

	eth_register(dev);

	cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div);
	priv->bus = miiphy_get_dev_by_name(dev->name);
	for_active_slave(slave, priv)
		cpsw_phy_init(dev, slave);

	return 1;
}

然後是smsc的一個註冊函式,註冊具體的乙太網晶片,這裡選擇lan8710:

檔案:net/phy/smsc.c

static struct phy_driver lan8710_driver = {
	.name = "SMSC LAN8710/LAN8720",
	.uid = 0x0007c0f0,
	.mask = 0xffff0,
	.features = PHY_BASIC_FEATURES,
	.config = &genphy_config_aneg,
	.startup = &genphy_startup,
	.shutdown = &genphy_shutdown,
};

int phy_smsc_init(void)
{
	phy_register(&lan8710_driver);
	phy_register(&lan911x_driver);
	phy_register(&lan8700_driver);

	return 0;
}

phy_smsc_init函式包含在phy_init()函式中,然後phy_init()函式包含在miiphy_init函式中,位於miiphyinit.c,然後該函式包含在eth_common_init函式中,位於eth.c檔案中,然後該函式包含在eth_initialize函式中,位於eth.c中。然後該函式包含在board_eth_init函式中,位於board.c檔案中,然後在uboot初始化時,呼叫board_eth_init函式從而完成網路驅動的註冊和初始化。

相關推薦

2015uboot啟動過程驅動結構分析

啟動流程和上篇博文介紹的rtems類似 首先是start.s: 在這裡選擇arm的arm7作為例子分析,程式碼:/arch/arm/cpu/armv7/start.s /* * armboot - Startup Code for OMAP3530/ARM Cortex

S3C6410開發全紀錄(三)《UBOOT中新增DM9000AE驅動

 我們獲得的UBOOT的程式碼中實際是有DM9000的網口驅動的,位於:driver/dm9000x.c在S3C6410的配置中,中並沒有將之開啟,而其他的晶片中有使用特別需要注意的是dm9000的驅動與dm9000AE的驅動還是有區別的,如果直接使用程式碼中自帶的dm900

精彩---rtl8139驅動程式分析

而另一類是普通的控制暫存器空間,這一部分對映完後CPU可以訪問來控制裝置工作。   現在我們回到上面pci_register_driver的第二步,如果找到相關裝置和我們的pci_device_id結構陣列對上號了,說明我們找到服務物件了,則呼叫rtl8139_init_one,它主要做了七件事:   ①

學習筆記 --- LINUX驅動框架分析

網絡卡的驅動很簡單,就是填充net_device結構體,其應用層到網路協議層核心已經完成了,我們的工作就是填寫這個net_device,然後註冊就可以了。 修正一下:上面第三步應該是:register_netdev 下面程式碼實現一個虛擬網絡卡,這裡沒有實際的網絡卡,只是

驅動流程分析

1.網絡卡驅動架構分析 1.1linux網路子系統 1.2.重要資料結構 1.3.網絡卡驅動架構分析 1.1linux網路子系統 linux網路子系統可以分為System call interface(系統呼叫介面),Protocol agnost

驅動收發包過程

網絡卡 網絡卡工作在物理層和資料鏈路層,主要由PHY/MAC晶片、Tx/Rx FIFO、DMA等組成,其中網線通過變壓器接PHY晶片、PHY晶片通過MII接MAC晶片、MAC晶片接PCI匯流排 PHY晶片主要負責:CSMA/CD、模數轉換、編解碼、串並轉換 MAC晶片主要

解決kvm虛擬機器啟動之後,eth0變為eth1問題

2018-12-19   故障前提 kvm虛擬機器遷移到其他伺服器上之後,重新啟動網絡卡會出現問題 例如原網絡卡名稱為eth0,遷移重啟之後會自動變為eth1 為什麼eth0會變成eth1? 很多Linux distribution使用udev動態管理裝置檔案,並根據裝置的資訊對其進

基於Exynos4412 cortex A9開發板的無線驅動移植過程

移植無線網絡卡的驅動: 準備工作: 1.無線網絡卡 2.首先在這個官網上[www.realtek.com.tw](無線網絡卡),下載相應網絡卡的驅動,本次下載的名稱為: 0001RTL8188

linux下啟動和關閉命令

 ifup、ifdown:linux命令   實時地手動修改一些網路介面引數,可以利用ifconfig來實現,如果是要直接以配置檔案,亦即是在 /etc/sysconfig/network-scripts裡面的ifcfg-ethx等檔案的設定引數來啟動的話,那就得要通過i

轉:linux下啟動和關閉命令

http://blog.sina.com.cn/s/blog_439f80c40101g54x.html 作者寫的很詳細。儲存下來,方便以後查詢,非常感謝  ifup、ifdown:linux命令  實時地手動修改一些網路介面引數,可以利用ifconfig來實現,如果是要直接以配置

netback的tasklet排程問題丟包的簡單分析

最近在萬兆網絡卡上測試,出現了之前千兆網絡卡沒有出現的一個現象,tasklet版本的netback下,vm進行發包測試,發現vif的interrupt預設繫結在cpu0上,但是vm發包執行時發現host上面cpu1, cpu2的ksoftirqd很高。 從之前的理解上來說

Ubuntu14.04 無線驅動安裝

由於新安裝的14.04是 沒有無線網絡卡驅動的,這裡需要自己安裝網絡卡驅動。 (第一步) 我們需要在win10下看到網絡卡型號 (第二步) 升級ubuntu核心(uname -sr可以看現在的核心版本) 在 http://kernel.ubuntu.com/~kernel

DPDK驅動載入、繫結和解綁

Igb_uio程式碼相關的可以分為三個部分:igb_uio核心驅動,核心uio框架,uio使用者態部分。 載入igb_uio模組與繫結dpdk網絡卡 a)載入dpdk驅動需要先載入uio:modprobe uio b)載入dpdk驅動的方法:/sbin/insmod  ig

ThinkPad E480安裝ubuntu後沒有無線驅動,找不到wifi的解決方案

先安裝的ubuntu版本是ubuntu-16.04.3-desktop-amd64.iso 安裝後通過cat /proc/version或者uname -rs檢視linunx核心版本,其linux核心版本為4.10。 網上查到linux4.15及以上的linux核心才能支援此筆記本的無線網絡

安裝完Ubuntu系統之後無法連線無線,有無線卻找不到驅動

今天給我的Mac裝完Ubuntu16.04之後,發現登入系統之後無法連線WIFI無線網路,筆記本是自帶無線網絡卡的,所以這個出現問題的原因只有一個,那就是沒有安裝好網絡卡驅動,而且Ubuntu自帶的相容網絡卡驅動並沒有起到作用。這個時候我查閱了一些網路上的相關資料,自己總結了一個解決辦法,相

Jetson tk1 安裝 Intel 7260ac 無線驅動

首先,利用Jetpack將Jetson TK1升級到最新的L4T (version 21.3 +) 如果工作環境能提供有線網路,請將網線插到開發板,在開發板L4T的terminal輸入以下指令來下載並安裝驅動: sudo apt-get install git git clon

centos7.5安裝無線驅動

本文主要參考: https://blog.csdn.net/yanshaoshuai/article/details/81148664 http://elrepo.org/tiki/wl-kmod 1. 概要 本篇部落格主要記錄在 centos7.5 環境下安裝 BCM

【Ubuntu16.04】安裝無線驅動

1、參考連結:https://blog.csdn.net/weijia_kmy/article/details/51304518 昨天下載了ubuntu16.0.4,安裝後發現沒有wifi可連線,於是上網查了一個晚上,都沒有可行的辦法。無奈今早就又下載ubuntu15.10安裝,發現可以連wifi

l(轉)Linux DM9000驅動程式完全分析

[置頂] Linux DM9000網絡卡驅動程式完全分析 分類: Linux裝置驅動程式第三版學習筆記 2011-02-26 16:11 3513人閱讀 評論(34) 收藏 舉報 說明1:本文分析基於核心原始碼版本為linux-2

LINUX核心升級 - 更新驅動

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!