--------------------------------------------------------------------------------
                         ROM CODE怎样从MMC启动
--------------------------------------------------------------------------------

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">


watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

ROM code将boot parameters的结构体指针通过R0寄存器传递给MLO,在start.s的reset部分,第一句指令就是:
bl save_boot_params.
5.07版本号中相关代码比較复杂。而7.00中就相对简单:
就是将R0的数据存储到r1所指的地址中,只存储了一个指针就返回了。


-------------------------------------------------------------------------

Start.s  Start

-------------------------------------------------------------------------
位于arch/arm/cpu/armv7/start.s

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

上电直接跳到reset异常处理例程


调用save_boot_params,保存boot參数。不详述。

continue...


cpy_clk_code是将DPLL的代码复制到SRAM中,暂不述。
cpu_init_crit仅仅在SPL阶段会被调用,用于setup important registers and memory timing.

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

接着调用lowlevel_init函数,位于arch/arm/cpu/armv7/omap-common/lowlevel_init.s文件。
从名字能够看出,该文件用于底层的初始化。


--------------------------------------------------------------------------------

lowlevel_init Start(lowlevel_init.s)

--------------------------------------------------------------------------------

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

这里首先建立一个暂时的栈,用于执行接下来c程序s_init。

当中LOW_LEVEL_SRAM_STACK定义在asm/arch/omap.h文件中面。


而0x4030B7FC位于MPU的L3 OCMC0区域。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

调用的函数s_init。位于board/ti/am335x/evm.c下。

在s_init中有几步非常关键


1、 preloader_console_init()用于初始化串口,调用serial_init(),该函数位于common/serial.c文件中面。


serial_init()函数首先检查当前有没有串口,显然没有,就仅仅能用默认串口default_serial_console结构。该结构定义在drivers/serial/serial.c中。


当中CONFIG_CONS_INDEX宏定义在include/configs/am335x_evm.h,定义为1表示使用UART0口。
这块是移植时候须要注意的地方。否则调试u-boot时候在默认的串口上不会信息打印。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

2、 enable_i2c0_pin_mux()
i2c_init()以及read_eeprom(),这三个函数主要适用于TI公司AM335x相关的板子。

     这一系列板子上面都有EEPROM而且存储了板子的信息。read_eeprom用于读取相关信息。
s_init
Continue...

定义变量is_ddr3用于选择初始化的对象,这也是移植时候须要注意的地方。
--------------------------------------------------------------------------------

lowlevel_init End(lowlevel_init.s)

--------------------------------------------------------------------------------


--------------------------------------------------------------------------------

call_board_init_f Start(start.s)

--------------------------------------------------------------------------------
Back to start.s
调用完cpu_init_crit后,start.s会继续。接着会调用board_init_f(),在调用之前会在内部SRAM中设立栈指针,
这样才干调用函数。由于函数调用须要入栈的操作。


1、栈指针值CONFIG_SYS_INIT_SP_ADDR
start.s又包括 config.h 文件(位于am335x/include/config.h,am335x是编译时候生成的,Makefile将与目标板相关的文件集中在此处)
config.h文件内容:


在configs/am335x_evm.h中定义了CONFIG_SYS_INIT_SP_ADDR:


即CONFIG_SYS_INIT_SP_ADDR = SRAM0_START + SRAM0_SIZE - GENERATED_GBL_DATA_SIZE
当中 SRAM0_START定义在hardware.h中,进入后可知 SRAM0_START = 0x402F0400,正是Memory Map中SRAM internel的首地址。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">


SRAM0_SIZE定义在cpu.h中。进入后可知 SRAM0_SIZE = 0x1B400,这个SIZE一直将SRAM延伸到OCMC0里面,结束地址为0x4030B800。



GENERATED_GBL_DATA_SIZE定义在generic-asm-offset.h(asm-offset.h包括此头文件)中。值为128。
这个size的空间是用于存储global_data结构的数据,存储空间以16字节对齐(这个并未证明,由于代码里面没有在不论什么地方提到将全局变量指针指向此地)。


总结一下。到这一步,在MPU的内部OCMC0区设置栈底SP = 0x4030B800 - 128
= 0x4030B780,并在栈底上面存储分配128 Bytes空间用于存储全局数据。
2、MLO重定位
board_init_f函数位于arch/arm/cpu/armv7/omap-common/spl.c。该函数唯一做的事情就是向relocate_code
函数传入三个參数。然后程序流程又回到start.s文件。


在board_init_f()函数调用start.s中的relocate_code函数。这里实现重定位(实现机理能够百度之),
重定位后。后面的puts不会执行了。由于relocate_code不会返回。见下图。


--------------------------------------------------------------------------------

relocate_code Start(start.s) 

--------------------------------------------------------------------------------
relocate_code的代码例如以下:
/*

* void relocate_code (addr_sp, gd, addr_moni)

*

* This "function" does not return, instead it continues in RAM

* after relocating the monitor code.

*

*/

     .globl     relocate_code

relocate_code:

     mov     r4, r0     /* save addr_sp */

     mov     r5, r1     /* save addr of gd */

     mov     r6, r2     /* save addr of destination */



     /* Set up the stack                                  */

stack_setup:

     mov     sp, r4



     adr     r0, _start

     cmp     r0, r6

     moveq     r9, #0          /* no relocation. relocation offset(r9) = 0 */

     beq     clear_bss          /* skip relocation */

     mov     r1, r6               /* r1 <- scratch for copy_loop */

     ldr     r3, _image_copy_end_ofs

     add     r2, r0, r3          /* r2 <- source end address         */



copy_loop:

     ldmia     r0!, {r9-r10}          /* copy from source address [r0]    */

     stmia     r1!, {r9-r10}          /* copy to   target address [r1]    */

     cmp     r0, r2               /* until source end address [r2]    */

     blo     copy_loop



#ifndef CONFIG_SPL_BUILD

     /*

     * fix .rel.dyn relocations

     */

     ldr     r0, _TEXT_BASE          /* r0 <- Text base */

     sub     r9, r6, r0          /* r9 <- relocation offset */

     ldr     r10, _dynsym_start_ofs     /* r10 <- sym table ofs */

     add     r10, r10, r0          /* r10 <- sym table in FLASH */

     ldr     r2, _rel_dyn_start_ofs     /* r2 <- rel dyn start ofs */

     add     r2, r2, r0          /* r2 <- rel dyn start in FLASH */

     ldr     r3, _rel_dyn_end_ofs     /* r3 <- rel dyn end ofs */

     add     r3, r3, r0          /* r3 <- rel dyn end in FLASH */

fixloop:

     ldr     r0, [r2]          /* r0 <- location to fix up, IN FLASH! */

     add     r0, r0, r9          /* r0 <- location to fix up in RAM */

     ldr     r1, [r2, #4]

     and     r7, r1, #0xff

     cmp     r7, #23               /* relative fixup?

*/

     beq     fixrel

     cmp     r7, #2               /* absolute fixup?

*/

     beq     fixabs

     /* ignore unknown type of fixup */

     b     fixnext

fixabs:

     /* absolute fix: set location to (offset) symbol value */

     mov     r1, r1, LSR #4          /* r1 <- symbol index in .dynsym */

     add     r1, r10, r1          /* r1 <- address of symbol in table */

     ldr     r1, [r1, #4]          /* r1 <- symbol value */

     add     r1, r1, r9          /* r1 <- relocated sym addr */

     b     fixnext

fixrel:

     /* relative fix: increase location by offset */

     ldr     r1, [r0]

     add     r1, r1, r9

fixnext:

     str     r1, [r0]

     add     r2, r2, #8          /* each rel.dyn entry is 8 bytes */

     cmp     r2, r3

     blo     fixloop

     b     clear_bss

_rel_dyn_start_ofs:

     .word __rel_dyn_start - _start

_rel_dyn_end_ofs:

     .word __rel_dyn_end - _start

_dynsym_start_ofs:

     .word __dynsym_start - _start



#endif     /* #ifndef CONFIG_SPL_BUILD */



clear_bss:

#ifdef CONFIG_SPL_BUILD

     /* No relocation for SPL */

     ldr     r0, =__bss_start

     ldr     r1, =__bss_end__

#else

     ldr     r0, _bss_start_ofs

     ldr     r1, _bss_end_ofs

     mov     r4, r6               /* reloc addr */

     add     r0, r0, r4

     add     r1, r1, r4

#endif

     mov     r2, #0x00000000          /* clear                   */



clbss_l:str     r2, [r0]          /* clear loop...              */

     add     r0, r0, #4

     cmp     r0, r1

     bne     clbss_l



/*

* We are done. Do not return, instead branch to second part of board

* initialization, now running from RAM.

*/

jump_2_ram:

/*

* 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

     ldr     r0, _board_init_r_ofs

     adr     r1, _start

     add     lr, r0, r1

     add     lr, lr, r9

     /* setup parameters for board_init_r */

     mov     r0, r5          /* gd_t */

     mov     r1, r6          /* dest_addr */

     /* jump to it ... */

     mov     pc, lr



_board_init_r_ofs:

     .word board_init_r - _start


从代码的最后能够看出来,最后mov pc,lr,是跳到重定位后的board_init_r函数处。

代码还是那段代码,仅仅是在内存中的位置变化了。


再回到board_init_f中调用relocate_code函数。传入三个參数:
     relocate_code(CONFIG_SPL_STACK, &g_data, CONFIG_SPL_TEXT_BASE);
第一个參数是栈指针:CONFIG_SPL_STACK
第二个參数是全局数据结构指针:&g_data
第三个參数是重定位的目的地址:CONFIG_SPL_TEX_BASE
relocate_code的代码是用汇编书写的。这里要提到的是C參数怎样传递给汇编语言的。这里必需要提到ABI和EABI。
ABI是Application Binary Interface的缩写,跟API非常类似。但ABI是比API更贴近硬件的一层接口。它规定的
是二进制代码之间的调用规则。

我们知道API是与机器硬件平台无关的接口,如熟悉的printf函数,不同的库的实现可能是不同的。可是它们的接口名称
与參数类型都是一样的。

ABI比API的要求更严格。它要求在寄存器级别遵守相同的接口规范。如函数调用的參数传递规则,

寄存器、堆栈的使用方式等。编译器被要求遵守相同的ABI规范,这样不同编译器编译出来的库(相同硬件)才干被别的
编译器使用。
EABI是使用与嵌入式场合的应用二进制接口。这里就简单提一下:函数调用时,传递的參数假设都小于32bit则使用
R0-R3传递參数。參数个数超出4个则使用STACK传递。因此为了代码的效率。程序猿应该尽量保证将函数的參数个数限制
在4个下面。

对于CONFIG_SPL_STACK,是LOW_LEVEL_SRAM_STACK的宏定义。


另外am335x_evm.h还包括hardware.h


hardware.h包括omap.h

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

在omap.h中有LOW_LEVEL_SRAM_STACK的宏定义,这个宏定义和前文提到调用s_init函数前的建立栈底是一样的。


因为栈生长的方向是向下的,所以栈底必须设置为高地址处。这个地址已经快接近OCMC0的底部。


对于CONFIG_SPL_TEXT_BASE。正是MPU内部SRAM的起始地址。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

--------------------------------------------------------------------------------

relocate_code End(start.s)

--------------------------------------------------------------------------------
总结一下:从信息打印看,我们的板子的stack生长方向是递减的。
有一点非常疑惑的是:在调用board_init_f之前,SP设置为0x4030B780。进入board_init_f后调用
relocate_code,传入的SP地址參数为0x4030B7FC,SP往上面移动了。这是为什呢?由于重定位后是不会从
relocate_code函数返回的,所以board_init_f的入栈參数会被抹掉但无所谓,可是能不能将这两次的SP设置成一样的呢?
(PS: TI-SDK-AM335X-EVM-07.00中堆栈的设置没有让人confused的地方了)


--------------------------------------------------------------------------------

call_board_init_f End(start.s)

--------------------------------------------------------------------------------

board_init_f函数调用relocate_code。该函数实现代码的搬迁。

从以下的图中能够看到:


_start处于内存位置:0x402F0400
在relocate_code中,
relocate_code:

     mov     r4, r0     /* save addr_sp */

     mov     r5, r1     /* save addr of gd */

     mov     r6, r2     /* save addr of destination */
stack_setup:

     mov     sp, r4

     adr     r0, _start

     cmp     r0, r6

     moveq     r9, #0          /* no relocation. relocation offset(r9) = 0 */

     beq     clear_bss          /* skip relocation */

     mov     r1, r6               /* r1 <- scratch for copy_loop */

     ldr     r3, _image_copy_end_ofs

     add     r2, r0, r3          /* r2 <- source end address         */
将_start载入到r0中,与r6比較。而r6是由r2传递过来的目标地址CONFIG_SPL_TEXT_BASE=0x402F0400。
因此会运行beq clear_bss处,即copy_loop的代码不会运行。

在代码里面增加宏开关。又一次编译后依旧能运行。证实了这个想法:
MLO阶段不会将自己copy到SRAM中,copy动作应该是由ROM Code实现的。
另外一个证明就是,ti-sdk-07.00版本号的u-boot代码中明白了没有在MLO阶段调用relocate_code,只在u-boot阶段调用。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

-------------------------------------------------------------------------

Start.s  End

-------------------------------------------------------------------------

--------------------------------------------------------------------------------

board_init_r Start(start.s)

--------------------------------------------------------------------------------
relocate_code结束的时候。跳到board_init_r函数处。该函数位于arch/arm/cpu/armv7/omap-common/spl.c。

该函数主要初始化内存、各个外设:
     mem_malloc_init()
     timer_init()
     i2c_init()
     spl_board_init()
然后选择从那个外设载入image。我们调试的时候从SD卡载入u-boot的image,所以关注spl_mmc_load_image函数。
--------------------------------------------------------------------------------

spl_mmc_load_image Start(board_init_r) 

--------------------------------------------------------------------------------
首先取得boot_device的序号。这个序号是定义在boot_params结构体的第三个成员项


omap_boot_device函数定义在arch/arm/cpu/armv7/omap-common/boot-common.c中。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

结构体omap_boot_parameters定义在,这个定义与最開始
时候的Booting Parameters Structure是一致的。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

将boot_device和boot_params的地址都打印出来。例如以下图所看到的:

能够看到boot device是8,相应的是MMC/SD port 0设备。boot_params结构体的地址是0x40303990。位于L3 0CMC0存储区,非常显然这个地址是由连接器分配的。位于“Downloaded Image”区域。
而在spl_mmc_load_image中最关键的部分是,


将boot_mode打印出来,2相应MMCSD_MODE_FAT模式。


另外。因为代码的添加。这儿能够看到boot_params结构体的地址变成了0x403039B8。

而mmc_load_image_fat中最重要的代码就是解析header和读出image。

spl_parse_image_header将header的中信息解析出来放在结构体spl_image里面,file_fat_read函数将image读到spl_image.load_addr所指向的缓冲区。
--------------------------------------------------------------------------------
                     spl_mmc_load_image End(board_init_r) 

--------------------------------------------------------------------------------

spl_image是非常重要的一个结构体。将其打印出来看看有什么。


spl_image的地址已经到了0x8000,0000。这已经是Externel SDRAM的首地址了。那么谁安排spl_image的地址的?
搜索一番,发现spl_image处于.bss区域,即未初始化区域,map里面将其放在0x8000000地址。

回过头来查看arch/arm/cpu/armv7/omap-common/u-boot-spl.lds链接脚本文件,能够看到:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3V4aWFuZ2xvbmdoYW9oYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

也就是说.bss段被指向sdram存储区域。map文件则显示链接器将spl_image安排在第一个。不知道这样的安排是否是有意为之?(后来从7.00上面证明并不是刻意安排。而是ld的行为)从map看。似乎是谁离lds文件更近谁出如今map的最前面。这样的安排是有些道理的。一定程度上能解释为什么spl_image在map上处于第一个。

从spl_image.os的数值能够得出,下一步就是运行jump_to_image_no_args()函数。

该函数首先typedef一个新类型,该类型是入參和返回值均为void的函数指针类型,而且用这个类型定义一个变量image_entry,将spl_image.entry_point赋值给它,最后运行这个函数,从汇编的角度看,就是将spl_image.entry_point赋值给PC,下一步就是跳转到SDRAM的0x80100000运行。

--------------------------------------------------------------------------------

board_init_r End(start.s)

--------------------------------------------------------------------------------

MLO阶段结束。

ti-sdk-evm-am335x-05.07 uboot分析(MLO跳转到u-boot之前)的更多相关文章

  1. ti processor sdk linux am335x evm Makefile hacking

    # # ti processor sdk linux am335x evm Makefile hacking # 说明: # 本文主要对TI的sdk中的Makefile脚本进行解读,是为了了解其工作机 ...

  2. ti processor sdk linux am335x evm /bin/create-sdcard.sh hacking

    #!/bin/bash # # ti processor sdk linux am335x evm /bin/create-sdcard.sh hacking # 说明: # 本文主要对TI的sdk中 ...

  3. ti processor sdk linux am335x evm /bin/setup-uboot-env.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-uboot-env.sh hacking # 说明: # 本文主要对TI的sdk中 ...

  4. ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking # 说明: # 本文主要对TI的s ...

  5. ti processor sdk linux am335x evm /bin/setup-tftp.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-tftp.sh hacking # 说明: # 本文主要对TI的sdk中的setu ...

  6. ti processor sdk linux am335x evm setup.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm setup.sh hacking # 说明: # 本文主要对TI的sdk中的setup.sh脚本进行解读 ...

  7. ti processor sdk linux am335x evm /bin/setup-host-check.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-host-check.sh hacking # 说明: # 本文主要对TI的sdk ...

  8. ti processor sdk linux am335x evm /bin/unshallow-repositories.sh hacking

    #!/bin/bash # # ti processor sdk linux am335x evm /bin/unshallow-repositories.sh hacking # 说明: # 本文主 ...

  9. ti processor sdk linux am335x evm /bin/setup-package-install.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-package-install.sh hacking # 说明: # 本文主要对T ...

随机推荐

  1. 数据库用varchar存储时间时会出现时间差解决办法

    用varchar存储时间,最后提取数据库时间字段会出现时间差问题. 当我们调用数据库时间字段时,会出现时间差,使得查询的数据查询不到,解决办法如下 CAST( 字段名as DATE) between ...

  2. Concurrency pattern

    In software engineering, concurrency patterns are those types of design patterns that deal with the  ...

  3. DELL inspiron 14-7467 进入安全模式方法

    您按住shift键不要松开,然后重启电脑,选择疑难解答-高级选项-启动设置-数字四 安全模式启动

  4. 正则效验url

    上篇文章讲到多主题的解决方案:简单暴力的TP5多主题方案 为了简化配置,所以将域名前的协议 http/https 截取了. 后台配置时就需要效验配置的格式是否正确,需要用到的正则代码如下: /*** ...

  5. luogu P4430 小猴打架(prufer编码与Cayley定理)

    题意 n个点问有多少种有顺序的连接方法把这些点连成一棵树. (n<=106) 题解 了解有关prufer编码与Cayley定理的知识. 可知带标号的无根树有nn-2种.然后n-1条边有(n-1) ...

  6. python学习笔记:第四天

    day04: 一.计算求值 num += 1 等价于 num = num + 1num -= 1 等价于 num = num - 1num *= 2 等价于 num = num * 2num /= 2 ...

  7. HDU 1532||POJ1273:Drainage Ditches(最大流)

    pid=1532">Drainage Ditches Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/327 ...

  8. MySQL 一台主机多实例root登录问题

    假设在一台机子上起多个MySQL实例. 比方port号为 3306. 3307. 3308 登录时候要选择不同的 mysql.sock文件 mysql -uroot -p123456 这一句 登录的是 ...

  9. win8装win7出现蓝屏的解决方式

    今天用PE装系统,在进入PE前会出现蓝屏: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzAxODcyMQ==/font/5a6L5L2T/fo ...

  10. vncserverpassword改动

    前几天去客户现场,客户说有測试库.Linux下的,帮忙给新建一个数据库,我这么热心的人.是吧 那就開始吧. 一般使用vnc搞图形安装.熟练的打开vnc.输入password,报错!!我愣了几秒,忽然反 ...