Bootloader(Vivi)源代码分析

汇编bne的问题 下面一段程序摘自《嵌入式Linux应用开发完全手册》page-95 memsetup:     @ 设置存储控制器以便使用SDRAM等外设     mov r1,     #MEM_CTL_BASE   @ 存储控制器的13个寄存器的开始地址     adrl    r2, mem_cfg_val              @ 这13个值的起始存储地址     add r3,     r 阅读详情

   Vivi 是韩国mizi 公司开发的bootloader, 适用于ARM9处理器。 Vivi有两种工作模式:启动加载模式和下载模式。启动加载模式可以在一段时间后(这个时间可更改)自行启动linux内核,这时vivi的默认模式。在下载模式下,vivi为用户提供一个命令行接口,通过接口可以使用vivi提供的一些命令,见下表:

 

命令

功能

   Load

把二进制文件载入Flash或RAM

   Part

操作MTD分区信息。显示、增加、删除、复位、保存MTD分区

   Param

设置参数

   Boot

启动系统

   Flash

管理Flash,如删除Flash的数据

 

 

 

 

1.2 vivi的配置与编译

1.2.1 建立交叉开发环境

1、在宿主机上安装标准Linux 操作系统:Redhat 9.0 ( 主机系统为win2000,用虚拟机vmware安装的Redhat 9.0,内核版本为2.4.18) 。

2、宿主机上安装交叉编译器。

我这边的2410开发板提供的光盘上已附交叉编译器工具:arm-linux-gcc-2.95.3(源码为cross-2.95.3.tar.bz2)。

先以root 用户的身份登陆到linux 下。

进入/usr/local 目录,创建名为arm的目录:

cd /usr/local

mkdir arm

将光盘提供的cross-2.95.3.tar.bz2解压到/usr/local/arm目录:

tar jxvf cross-2.95.3.tar.bz2 –C /usr/local/arm

 

然后修改修改PATH 变量:为了可以方便使用arm-linux-gcc编译器系统, 把arm-linux工具链目录加入到环境变量PATH中:

修改/etc/profile文件,添加pathmunge /usr/local/arm/2.95.3/bin即可。

# Path manipulation

if [ `id -u` = 0 ]; then

        pathmunge  /sbin

        pathmunge  /usr/sbin

        pathmunge  /usr/local/sbin

        pathmunge  /usr/local/arm/2.95.3/bin

fi

                                                                                

pathmunge /usr/X11R6/bin after

设置环境变量后,最好是重启或注销一下,这样设置的环境变量才能生效。

 

1.2.2 配置和编译vivi

如果vivi的源代码已根据开发板作了相应改动,则需要对源代码进行配置和编译,以生成烧入flash的vivi 二进制映象文件。

由于vivi要用到kernel的一些头文件,所以需要kernel的源代码,所以先要把linux的kernel准备好。将vivi和kernel都解到相应目录下(例如我将光盘提供的vivi源代码解压到/home/chenjun目录下,光盘提供的Linux kernel源码kernel-h2410eb.041024.tar.gz也解压到/home/chenjun目录下,解压后的文件名为kerne-h2410eb)。

然后需修改/vivi/Makefile里的一些变量设置:

Ø        LINUX_INCLUDE_DIR = /kernel/include/

(LINUX_INCLUDE_DIR 为kernel/include的对应目录,我的是/home/chen/kerne-h2410eb /include/)

因此修改为:

LINUX_INCLUDE_DIR = /home/chenjun/ kerne-h2410eb/include/

 

Ø        CROSS_COMPILE   = /usr/local/arm/2.95.3/bin/arm-linux-

(CROSS_COMPILE 为arm-linux安装的相应目录,我的是/usr/local/arm/2.95.3/bin/arm-linux-)

因此修改为:

CROSS_COMPILE   = /usr/local/arm/2.95.3/bin/arm-linux-

 

Ø        ARM_GCC_LIBS     = /usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3

(需根据你arm-linux的安装目录修改,我的是/usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3)

 

进入/vivi目录执行make distclean。(目的是确保编译的有效性,在编译之前将vivi里所有的“*.o”和“*.o.flag”文件删掉)

进入/vivi目录里,输入“make menuconfig”,开始选择配置。可以Load一个写好的配置文件也可以自己修改试试。注意Exit时一定要选“Yes”保存配置。

再输入“make”正式开始编译,一会儿就完了。如果不报错,在/vivi里面就有你自己的“vivi”了。这个就是后面要烧写到flash中的bootloader。

1.3 vivi代码分析

vivi的代码包括arch,init,lib,drivers和include等几个目录,共200多条文件。

Vivi主要包括下面几个目录:

       arch:此目录包括了所有vivi支持的目标板的子目录,例如s3c2410目录。

       drivers:其中包括了引导内核需要的设备的驱动程序(MTD和串口)。MTD目录下分map、nand和nor三个目录。

       init:这个目录只有main.c和version.c两个文件。和普通的C程序一样,vivi将从main函数开始执行。

       lib:一些平台公共的接口代码,比如time.c里的udelay()和mdelay()。

       include:头文件的公共目录,其中的s3c2410.h定义了这块处理器的一些寄存器。Platform/smdk2410.h定义了与开发板相关的资源配置参数,我们往往只需要修改这个文件就可以配置目标板的参数,如波特率、引导参数、物理内存映射等。

 

 

 

 

1.4 vivi的运行

vivi的运行也可以分为两个阶段:

1.4.1 vivi的第一阶段

完成含依赖于CPU的体系结构硬件初始化的代码,包括禁止中断、初始化串口、复制自身到RAM等。相关代码集中在head.S(/vivi/arch/s3c2410目录下):

Head.S:

 

#include "config.h"

#include "linkage.h"

#include "machine.h"

 

@ Start of executable code

 

ENTRY(_start)

ENTRY(ResetEntryPoint)

 

@

@ Exception vector table (physical address = 0x00000000)  ;异常向量表物理地址

@

 

@ 0x00: Reset                                                                           ;复位

       b     Reset

 

@ 0x04: Undefined instruction exception                              ;未定义的指令异常

UndefEntryPoint:

       b     HandleUndef

 

@ 0x08: Software interrupt exception                                         ;软件中断异常

SWIEntryPoint:

       b     HandleSWI

 

@ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort)  ;内存操作异常

PrefetchAbortEnteryPoint:

       b     HandlePrefetchAbort

 

@ 0x10: Data Access Memory Abort                                         ;数据异常

DataAbortEntryPoint:

       b     HandleDataAbort

 

@ 0x14: Not used                                                                      ;未使用

NotUsedEntryPoint:

       b     HandleNotUsed

 

@ 0x18: IRQ(Interrupt Request) exception                                 ;慢速中断处理

IRQEntryPoint:

       b     HandleIRQ

 

@ 0x1c: FIQ(Fast Interrupt Request) exception                          ;快速中断处理

FIQEntryPoint:

       b     HandleFIQ

 

@

@ VIVI magics

@

 

@ 0x20: magic number so we can verify that we only put

       .long   0

@ 0x24:

       .long   0

@ 0x28: where this vivi was linked, so we can put it in memory in the right place

       .long   _start

@ 0x2C: this contains the platform, cpu and machine id

       .long   ARCHITECTURE_MAGIC

@ 0x30: vivi capabilities

       .long   0

#ifdef CONFIG_PM                                             ;vivi考虑不需要使用电源管理

@ 0x34:

       b     SleepRamProc

#endif

#ifdef CONFIG_TEST

@ 0x38:

       b     hmi

#endif

 

 

@

@ Start VIVI head

@

Reset:

       @ disable watch dog timer                                     ;禁止看门狗计时器

mov r1, #0x53000000                                           ;WTCON寄存器地址是

0x53000000,清0

       mov r2, #0x0

       str   r2, [r1]

 

#ifdef CONFIG_S3C2410_MPORT3                  ;不符合条件,跳到下面的关中断

/**** 在/vivi/include/autoconf.h中#undef  CONFIG_S3C2410_MPORT3******/

       mov r1, #0x56000000                                           ;GPACON寄存器地址是

0x56000000

       mov r2, #0x00000005

       str   r2, [r1, #0x70]                                                      ;配置GPHCON寄存器

       mov r2, #0x00000001

       str   r2, [r1, #0x78]                                                      ;配置GPHUP寄存器

       mov r2, #0x00000001

       str r2, [r1, #0x74]                                                  ;配置GPHDAT寄存器

#endif

 

       @ disable all interrupts                                           ;禁止全部中断

       mov r1, #INT_CTL_BASE

       mov r2, #0xffffffff

       str   r2, [r1, #oINTMSK]                                             ;掩码关闭所有中断

       ldr   r2, =0x7ff

       str   r2, [r1, #oINTSUBMSK] 

 

       @ initialise system clocks                                              ;初始化系统时钟

       mov r1, #CLK_CTL_BASE

       mvn r2, #0xff000000

       str   r2, [r1, #oLOCKTIME]

 

       @ldr      r2, mpll_50mhz

       @str       r2, [r1, #oMPLLCON]

#ifndef CONFIG_S3C2410_MPORT1                               ;满足条件,向下执行

/**** 在/vivi/include/autoconf.h中#undef  CONFIG_S3C2410_MPORT1******/

       @ 1:2:4

       mov r1, #CLK_CTL_BASE

       mov r2, #0x3

       str   r2, [r1, #oCLKDIVN]

 

       mrc p15, 0, r1, c1, c0, 0           @ read ctrl register

       orr   r1, r1, #0xc0000000          @ Asynchronous 

       mcr p15, 0, r1, c1, c0, 0           @ write ctrl register

 

       @ now, CPU clock is 200 Mhz                             ;CPU的频率是200MHz

       mov r1, #CLK_CTL_BASE

       ldr   r2, mpll_200mhz

       str   r2, [r1, #oMPLLCON]

#else

       @ 1:2:2

    mov r1, #CLK_CTL_BASE

    ldr r2, clock_clkdivn

    str r2, [r1, #oCLKDIVN]

 

    mrc p15, 0, r1, c1, c0, 0       @ read ctrl register

    orr r1, r1, #0xc0000000     @ Asynchronous

    mcr p15, 0, r1, c1, c0, 0       @ write ctrl register

 

    @ now, CPU clock is 100 Mhz                                   ;CPU的频率是100MHz

    mov r1, #CLK_CTL_BASE

    ldr r2, mpll_100mhz

    str r2, [r1, #oMPLLCON]

#endif

       bl    memsetup                                                              ;跳转到memsetup函数

/*****************************

Memsetup函数的实现:

ENTRY(memsetup)

       @ initialise the static memory

 

       @ set memory control registers                       ;设置内存控制寄存器的初值

       mov r1, #MEM_CTL_BASE

       adrl r2, mem_cfg_val

/*******************

@

@ Data Area

@

@ Memory configuration values

.align 4

mem_cfg_val:                                                                                                                       ;定义好的13*4=52个字节初值

       .long       vBWSCON                ;在/vivi/include/platform/smdk2410.h中赋值

/******   SDRAM从32位变成16位,需要修改vBWSCON的值 ******/

       .long       vBANKCON0

       .long       vBANKCON1

       .long       vBANKCON2

       .long       vBANKCON3

/**********  网卡控制器vBANKCON3的值可能需要修改  **************/

       .long       vBANKCON4

       .long       vBANKCON5

       .long       vBANKCON6

/****** SDRAM从32位变成16位,可能需要修改vBANKCON6的值 ******/

       .long       vBANKCON7

       .long       vREFRESH

       .long       vBANKSIZE

/****** SDRAM从64MB变成32MB,需要修改vBANKSIZE的值 ******/

       .long       vMRSRB6

       .long       vMRSRB7

********************/

       add r3, r1, #52

1:    ldr   r4, [r2], #4

       str   r4, [r1], #4

       cmp r1, r3

       bne  1b                                      ;循环操作,直到13个寄存器赋值完成

 

       mov pc, lr

*******************************/

#ifdef CONFIG_PM                        ;vivi考虑不需要使用电源管理

       @ Check if this is a wake-up from sleep 

       ldr   r1, PMST_ADDR

       ldr   r0, [r1]

       tst    r0, #(PMST_SMR)

       bne  WakeupStart                      ;查看状态,判断是否需要跳转到WakeupStart

#endif

 

 

#ifdef CONFIG_S3C2410_SMDK                      ;SMDK开发板使用

       @ All LED on                                                ;点亮开发板上的LED

       mov r1, #GPIO_CTL_BASE

       add r1, r1, #oGPIO_F                                   ;LED使用GPIOF组的管脚

ldr   r2,=0x55aa                 ;使能EINT0,EINT1,EINT2,EINT3,

;另四个管脚配置成输出,屏蔽EINT4,5,6,7

       str   r2, [r1, #oGPIO_CON]

       mov r2, #0xff

       str   r2, [r1, #oGPIO_UP]         ;disable the pull-up function

       mov r2, #0x00

       str   r2, [r1, #oGPIO_DAT]

#endif

 

#if 0

       @ SVC

       mrs  r0, cpsr

       bic   r0, r0, #0xdf

       orr   r1, r0, #0xd3

       msr  cpsr_all, r1

#endif

 

       @ set GPIO for UART                                   ;设置串口

       mov r1, #GPIO_CTL_BASE

       add r1, r1, #oGPIO_H                                   ;设置GPIO_H组管脚为串口

       ldr   r2, gpio_con_uart

       str   r2, [r1, #oGPIO_CON]

       ldr   r2, gpio_up_uart

       str   r2, [r1, #oGPIO_UP] 

/*************************

@ inital values for GPIO

gpio_con_uart:

       .long       vGPHCON   ;vGPHCON在/vivi/include/platform/smdk2410.h中赋值

                                          ;#define vGPHCON               0x0016faaa

                                          ;GPIO_H配置为nCTS0,nRTS0, RXD0,TXD0, RXD1,

;TXD1,nCTS1,nRTS1,

 

/****  三个串口都使能,可能需要修改#define vGPHCON 0x0016aaaa   ****/

 

gpio_up_uart:

       .long       Vgphup         ;同上#define vGPHUP                  0x000007ff

                                          ;The pull-up function is disabled.

************************/

 

       bl    InitUART             ;跳转到InitUART串口初始化函数

/****************************************************

@ Initialize UART

@

@ r0 = number of UART port

InitUART:

       ldr   r1, SerBase

/*******************

.align 4                               ;缺省情况下在vivi中只初始化了UART0

SerBase:

#if defined(CONFIG_SERIAL_UART0)

       .long UART0_CTL_BASE        ;基地址在/vivi/include/s3c2410.h中定义

#elif defined(CONFIG_SERIAL_UART1)

       .long UART1_CTL_BASE

#elif defined(CONFIG_SERIAL_UART2)

       .long UART2_CTL_BASE

#else

#error not defined base address of serial

#endif

********************/

       mov r2, #0x0

       str   r2, [r1, #oUFCON]

       str   r2, [r1, #oUMCON]

       mov r2, #0x3

       str   r2, [r1, #oULCON]

       ldr   r2, =0x245

       str   r2, [r1, #oUCON]

#define UART_BRD ((50000000 / (UART_BAUD_RATE * 16)) - 1)

       mov r2, #UART_BRD

       str   r2, [r1, #oUBRDIV]

 

       mov r3, #100

       mov r2, #0x0

1:    sub  r3, r3, #0x1

       tst    r2, r3

       bne  1b

 

#if 0

       mov r2, #'U'

       str   r2, [r1, #oUTXHL]

 

1:    ldr   r3, [r1, #oUTRSTAT]

       and  r3, r3, #UTRSTAT_TX_EMPTY

       tst    r3, #UTRSTAT_TX_EMPTY

       bne  1b  

 

       mov r2, #'0'

       str   r2, [r1, #oUTXHL]

 

1:    ldr   r3, [r1, #oUTRSTAT]

       and  r3, r3, #UTRSTAT_TX_EMPTY

       tst    r3, #UTRSTAT_TX_EMPTY

       bne  1b  

#endif

 

       mov pc, lr

****************************************************/

 

#ifdef CONFIG_DEBUG_LL                        ;打印调试信息,缺省未定义

       @ Print current Program Counter

       ldr   r1, SerBase

       mov r0, #'/r'

       bl    PrintChar

       mov r0, #'/n'

       bl    PrintChar

       mov r0, #'@'

       bl    PrintChar

       mov r0, pc

       bl    PrintHexWord

#endif

 

 

#ifdef CONFIG_BOOTUP_MEMTEST

       @ simple memory test to find some DRAM flaults.

       bl    memtest

#endif

 

#ifdef CONFIG_S3C2410_NAND_BOOT         ;从NAND Flash启动

       bl    copy_myself                              ;跳转到copy_myself函数

/**********************************************

@

@ copy_myself: copy vivi to ram

@

copy_myself:

       mov r10, lr

 

       @ reset NAND

       mov r1, #NAND_CTL_BASE

       ldr   r2, =0xf830          @ initial value

       str   r2, [r1, #oNFCONF]

       ldr   r2, [r1, #oNFCONF]

       bic   r2, r2, #0x800             @ enable chip

       str   r2, [r1, #oNFCONF]

       mov r2, #0xff        @ RESET command

       strb r2, [r1, #oNFCMD]

       mov r3, #0                   @ wait

1:    add r3, r3, #0x1

       cmp r3, #0xa

       blt   1b

2:    ldr   r2, [r1, #oNFSTAT]    @ wait ready

       tst    r2, #0x1

       beq 2b

       ldr   r2, [r1, #oNFCONF]

       orr   r2, r2, #0x800             @ disable chip

       str   r2, [r1, #oNFCONF]

 

       @ get read to call C functions (for nand_read())

       ldr   sp, DW_STACK_START  @ setup stack pointer

       mov fp, #0                   @ no previous frame, so fp=0

 

       @ copy vivi to RAM

       ldr   r0, =VIVI_RAM_BASE

/*********在/vivi/linux/platform/smdk2410.h中定义

#define VIVI_RAM_BASE              (DRAM_BASE + DRAM_SIZE - VIVI_RAM_SIZE)

***************************************/

       mov     r1, #0x0

       mov r2, #0x20000              ;0x20000-〉128k字节

       bl    nand_read_ll         ;nand_read_ll在/vivi/arch/s3c2410/nand_read.c中定义

                                          ;r0,r1,r2分别为函数的三个参数

                                          ;从NANDFlash的0地址拷贝128k到SDRAM指定处

       tst    r0, #0x0

       beq ok_nand_read

#ifdef CONFIG_DEBUG_LL

bad_nand_read:

       ldr   r0, STR_FAIL

       ldr   r1, SerBase

       bl    PrintWord

1:    b     1b          @ infinite loop

#endif

      

ok_nand_read:

#ifdef CONFIG_DEBUG_LL

       ldr   r0, STR_OK

       ldr   r1, SerBase

       bl    PrintWord

#endif

 

       @ verify

       mov r0, #0

       ldr   r1, =0x33f00000

       mov r2, #0x400    @ 4 bytes * 1024 = 4K-bytes

go_next:

       ldr   r3, [r0], #4

       ldr   r4, [r1], #4

       teq  r3, r4

       bne  notmatch

       subs       r2, r2, #4

       beq done_nand_read  

       bne  go_next

notmatch:

#ifdef CONFIG_DEBUG_LL

       sub  r0, r0, #4

       ldr   r1, SerBase

       bl    PrintHexWord

       ldr   r0, STR_FAIL

       ldr   r1, SerBase

       bl    PrintWord

#endif

1:    b     1b

done_nand_read:

 

#ifdef CONFIG_DEBUG_LL

       ldr   r0, STR_OK

       ldr   r1, SerBase

       bl    PrintWord

#endif

 

       mov pc, r10                        ;vivi拷贝到SDRAM完成,函数返回

*********************************/

       @ jump to ram

       ldr   r1, =on_the_ram

       add pc, r1, #0

       nop

       nop

1:    b     1b          @ infinite loop

 

on_the_ram:

#endif

 

#ifdef CONFIG_DEBUG_LL

       ldr   r1, SerBase

       ldr   r0, STR_STACK

       bl    PrintWord

       ldr   r0, DW_STACK_START

       bl    PrintHexWord

#endif

 

       @ get read to call C functions

       ldr   sp, DW_STACK_START  @ setup stack pointer

       mov fp, #0                   @ no previous frame, so fp=0

       mov a2, #0                  @ set argv to NULL

 

       bl    main                     @ call main

 

       mov pc, #FLASH_BASE          @ otherwise, reboot

 

@

@ End VIVI head

@

 

 

1.4.2 vivi的第二阶段

vivi的第二阶段是从main()函数开始,同一般的C语言程序一样,该函数在/init/main.c文件中,总共可以分为8个步骤。

(1)    函数开始,通过putstr(vivi_banner)打印出vivi的版本。Vivi_banner在/init/version.c文件中定义

(2)    对开发板进行初始化(board_init函数),board_init是与开发板紧密相关的,这个函数在/arch/s3c2410/smdk.c文件中。开发板初始化主要完成两个功能,时钟初始化(init_time())和通用IO口设置(set_gpios())。

void set_gpios(void)

{

                            GPACON  = vGPACON;

                            GPBCON  = vGPBCON;

                            GPBUP   = vGPBUP;

                            GPCCON  = vGPCCON;

                            GPCUP   = vGPCUP;

                            GPDCON  = vGPDCON;

                            GPDUP   = vGPDUP;

                            GPECON  = vGPECON;

                            GPEUP   = vGPEUP;

                            GPFCON  = vGPFCON;

                            GPFUP   = vGPFUP;

                            GPGCON  = vGPGCON;

                            GPGUP   = vGPGUP;

                            GPHCON  = vGPHCON;

                            GPHUP   = vGPHUP;

                            EXTINT0 = vEXTINT0;

                            EXTINT1 = vEXTINT1;

                            EXTINT2 = vEXTINT2;

}

其中,GPIO口在smdk2410.h(/vivi/include/platform/目录下)文件中定义。

(3)    内存映射初始化和内存管理单元的初始化工作:

mem_map_init();

mmu_init();

这两个函数都在/arch/s3c2410/mmu.c文件中。

void mem_map_init(void)

{

#ifdef CONFIG_S3C2410_NAND_BOOT

  mem_map_nand_boot();

#else

  mem_map_nor();

#endif

  cache_clean_invalidate();

  tlb_invalidate();

}

 

如果配置vivi时使用了NAND作为启动设备,则执行mem_map_nand_boot(),否则执行mem_map_nor()。这里要注意的是,如果使用NOR启动,则必须先把vivi代码复制到RAM中。这个过程是由copy_vivi_to_ram()函数来完成的。代码如下:
     static void copy_vivi_to_ram(void)

{

  putstr_hex("Evacuating 1MB of Flash to DRAM at 0x", VIVI_RAM_BASE);

  memcpy((void *)VIVI_RAM_BASE, (void *)VIVI_ROM_BASE, VIVI_RAM_SIZE);

}

VIVI_RAM_BASE、VIVI_ROM_BASE、VIVI_RAM_SIZE这些值都可以在smdk2410.h中查到,并且这些值必须根据自己开发板的RAM实际大小修改。这也是在移植vivi的过程中需要注意的一个地方。

mmu_init()函数中执行了arm920_setup函数。这段代码是用汇编语言实现的,针对arm920t核的处理器。

 

(4)    初始化堆栈,heap_init()。(定义在/vivi/lib/heap.c文件中)

int heap_init(void)

{

                            return mmalloc_init((unsigned char *)(HEAP_BASE), HEAP_SIZE);

}

(5)    初始化mtd设备,mtd_dev_init()。

int mtd_init(void)

{

                     int ret;

 

#ifdef CONFIG_MTD_CFI

                            ret = cfi_init();

#endif

#ifdef CONFIG_MTD_SMC

                            ret = smc_init();

#endif

#ifdef CONFIG_S3C2410_AMD_BOOT

                            ret = amd_init();

#endif

 

                     if (ret) {

                            mymtd = NULL;

                            return ret;

                                   }

                     return 0;

}

这几个函数可以在/drivers/mtd/maps/s3c2410_flash.c里找到。

(6)    初始化私有数据,init_priv_data()。(定义在/vivi/lib/priv_data/rw.c文件中)

(7)    初始化内置命令,init_builtin_cmds()。

通过add_command函数,加载vivi内置的几个命令。

(8)    启动boot_or_vivi()。

启动成功后,将通过vivi_shell()启动一个shell(如果配置了CONFIG_SERIAL_TERM),此时vivi的任务完成。

 

 

 

 

 

 

 

 

 

 

1.5 启动代码执行流程图

 

            

(1)head.s代码执行流程            (2)main.c代码执行流程

 

 

 

1.6 vivi的配置文件

 

Vivi的初始配置文件位置:/vivi/arch/def-configs/smkd2410, 通过make menuconfig 修改后的配置保存在这个文件中,我们也可以载入一个自己的配置文件来进行编译。

vivi源代码 vivi源代码 供有兴趣的同志们下载 立即下载

相关推荐

vivi bootloader源码

MIZI Research 公司 的vivi源码,可用于学习移植。$make distclean $make menuconfig

vivi源代码分析2

现在进入bootloader之vivi分析的第二阶段,这部分使用C语言实现,部分代码采取内嵌汇编的方式。这里需要用到GNU GCC内嵌汇编的知识,这部分基础还没有具备,需要学习。     下面先按照流程进行分析。需要注意的是,此部分内容并非完全按照原版的vivi源代码,而是加入了自己的理解。另外,对非常简单、google出一片而且有分析正确的部分,在这里就简化了,不做详细分析,只是对网上没

menuconfig的专栏 1513

详细的vivi源码分析

vivi的源码分析,详细的讲述了linux的bootloader的启动代码vivi的第一及第二阶段的源码分析!

从vivi虚拟摄像头驱动开始分析v4l2

vivi 代码在线查看 https://elixir.bootlin.com/linux/v3.0.101/source/drivers/media/video/vivi.c 这是一个比较老的版本,但是比较适合我们入门v4l2。

ldl617的专栏 3567

gmsv源代码c语言,石器时代ABLua的原理、简介、过程、运用、收发

操作原理(一)服务端:服务器源文件客户端:客户所操作的程序(既是游戏客户端)接口:既是某项功能(例如:鼠标点击,文字发送,战斗,观战,人物动作等)返回的值ABlua:在源代码中添加的整套引擎作为回调接口--lua所实现的功能是基于服务端源码添加的接口由该接口与客户端发送封包实现功能源码里是否有ABlua回调接口?例如:源码里的gmsv/battle.c文件(既是战斗回调文件)以下为简单描述C给予l...

weixin_35223575的博客 2408

提取abaqus中节点集合的应力应变

节点是没有应力应变的,只有积分点才有,所以直接在odb文件里面用FieldOutput是整不出来的(结果是个空列表),只能用session这种让abaqus自己帮你处理。具体的代码需要根据自己操作的时候abaqus.rpy这个文件中代码的变化来更改。

蓝胖子的博客 4553

汇编 bne 1b

以前看过的汇编代码只有b,bl和bne label等,从未见过bne 1b,今天在看韦东山老师的《Linux完全开发手册》第六章有如下代码: 1: ldr r4,[r2],#4 str r4,[r1],#4 cmp r1,r3 bne 1b 顿时觉得代码写错了,最后一句应该是bne 1,但是后面居然还有一个1的标号,同样还有bne 1b语句,后面在网上查了之后...

xunmengxiaozi的博客 787

ADS谐波平衡仿真自动优化报错?三步搞定HB控件设置(附常见错误排查)

本文针对ADS谐波平衡仿真在自动优化中常见的报错问题,提供了三步核心排查法。首先检查并禁用HB控件中可能导致冲突的小信号仿真模式,其次合理化仿真频率与扫描参数设置,最后审视优化变量与目标的定义。通过精准配置HB控件以适配自动优化流程,能有效解决大多数仿真失败问题,确保非线性电路设计顺利进行。

c2d3e4f的博客 789

s3c2410的Bootloader(Vivi)源代码分析

1.1 Vivi简介Vivi 是韩国mizi 公司开发的bootloader, 适用于ARM9处理器。 Vivi有两种工作模式:启动加载模式和下载模式。启动加载模式可以在一段时间后(这个时间可更改)自行启动linux内核,这时vivi的默认模式。在下载模式下,vivi为用户提供一个命令行接口,通过接口可以使用vivi提供的一些命令,见下表:命令功能Load把二进制文件载入Flash或RAMPart操作MTD分区信息。显示、增加、删除、复位、保存MTD分区Param设置参数Boot启动系统Flash管理Fla

YOU_ARE_MY_FAVORITE的专栏 1026

【CubeMX】STM32G474 HRTIM 死区时间与互补PWM实战解析

本文深入解析STM32G474的HRTIM高分辨率定时器在互补PWM生成与死区时间配置中的应用。通过CubeMX工具详细演示时钟配置、单路PWM基础、互补输出与死区时间设置,并结合逆变器等电力电子实战案例,帮助开发者避免直通风险,优化系统性能。

efc12345678的博客 746

基于PID的定速巡航控制系统设计【MATLAB源码+Word文档】

本文详细介绍了定速巡航控制是一种车辆驾驶辅助系统,它能让驾驶者在高速或长途驾驶时,设定一个固定的车速,然后车辆会自动维持这个速度行驶,无需驾驶者持续踩油门。这大大减轻了驾驶者的疲劳,同时也提高了行驶的安全性。PID定速巡航控制系统是一种利用比例(Proportional)、积分(Integral)和微分(Derivative)控制算法来实现车辆定速巡航的先进系统。这种系统能够根据设定的速度,自动调整油门开度或制动力度,使车辆保持恒定的速度行驶。这种控制系统具有响应速度快、控制精度高、稳定性好等优点。

weixin_761237174的博客 1670

vivi开发笔记(二):软件架构分析

原文地址:vivi开发笔记(二):软件架构分析 作者:piaoxiang 文章说明:calmarrow(lqm)原创 文章引自:http://piaoxiang.cublog.cn      虽然想写《vivi软件架构分析》,但是对软件架构并没有清晰的认识。只是以学习的态度,去尽可能的理解吸收vivi的设计思想,以后可以

wangjilebeishang的专栏 944

通用抓取————6D位姿估计

这意味着算法在没有物体的先验知识(如 CAD 模型)的情况下,依然能够通过神经网络捕捉物体的外观、形状和几何特征,生成相关的 6D 位姿估计。通过输入物体类别的描述,算法能够推断出该类别物体的位姿和尺度,无需特定物体的 CAD 模型。在这个坐标空间中,物体的位姿和尺度都是已知的,基于这个标准化表示,算法可以对输入图像中的物体进行 6D 位姿和尺寸的估计。○优势: ICP 是一种非常有效的位姿优化算法,特别适合精细调整物体的位姿,确保最终估计的位姿与真实物体的点云或模型高度一致。

具身机器人和通用AI 2380

bootloader开发阶段总结以及可能会碰到的问题

<br />到今天,vivi源代码基本分析完毕。对bootloader有了更深层的认识。在此期间,仔细阅读了毛德操、胡希明先生编著的《嵌入式系统--采用公开源代码和StrongARM/XScale处理器》第七章:嵌入式系统的引导和装入。看了看出版时间,才明白牛人詹荣开或许也受惠于此书。他在IBM Development上发表的那篇《嵌入式bootloader技术内幕》一文,后来在sourceforge上的开源项目jtager,在此书中有详尽的描述。(当然,他们可能是独立研究的。)两者结合起来看,对自己的帮助

liangkaiming的专栏 5778

基于Linux的PCIe设备驱动开发入门到精通-- 11.2 锁机制与并发控制 (自旋锁、互斥锁) 11.3 性能瓶颈分析与优化建议

本文探讨Linux驱动开发中的性能优化方法论,重点聚焦并发控制与性能瓶颈分析。从锁机制选择(自旋锁、互斥锁等)到工具使用(ftrace、perf),详细介绍了定位锁竞争和CPU热点的实战步骤,包括ftrace事件跟踪和perf火焰图分析。针对常见性能瓶颈(CPU/内存/I/O/锁竞争),提出了锁粒度优化、无锁结构替换、中断处理优化等解决方案。强调性能优化需要理论结合实践,通过"假设-测量-验证"的循环持续迭代。为开发者提供了一套从问题定位到解决的完整方法论,助力开发高性能工业级驱动。

MHD0815的博客 128

游戏开发:逻辑与渲染分离技术解析

游戏开发中逻辑与渲染分离的架构设计 本文系统阐述了游戏开发中逻辑与渲染分离的设计原则与实践方法。文章首先定义了核心概念:逻辑层负责游戏规则与状态,渲染层处理视觉表现,二者通过数据模型层进行通信。通过历史回顾,揭示了从早期混合架构到现代分层设计的演变过程。 在技术实现层面,文章详细分析了分离架构的优势:性能优化、流畅度控制、测试便利性、扩展灵活性以及团队协作效率。提供了Unity和Unreal两大引擎的具体实现方案,包括代码示例、分层模型和最佳实践。特别探讨了网络同步、客户端预测、插值处理等关键技术难点。 文

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1060

实验二.Bootloader实验:vivi移植

 实验二  Bootloader实验:VIVI移植 实验目的:了解交叉编译器,学会运用。进一步加深对课上所学知识的理解,对Bootloader的理解,完成对VIVI的移植。实验内容:一.说明什么是交叉编译器,实验中使用的是什么交叉编译器;①交叉编译器是在一个架构下用来编译在另一个架构上运行的目标文件程序的编译器②使用的是arm-linux-gcc-2.95.2二

梦剧场OT 1578

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Bootloader的启动流程与VIvi

BOOTLOADER的启动流程    大多书分为两个阶段,第一个阶段主要是包含依赖于CPU的体系结构的硬件初始化代码,通常都是用汇编语言来实现的。这个阶段的任务有: ●     基本的硬件设备初始化(屏蔽所有中断、关闭处理器内部指令/数据CACHE等) ●     为第二阶段准备RAM空间 ●     如果是从某个固态存储媒质中,则复制BOOTLOADER的第二阶段代码到RAM ●    

李东军博客 2125

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

vivi源代码分析1

通过vivi研究bootloader有一段时间了,基本是在与之相关的基础方面做工作,还没有真正深入研究vivi。以后的学习重心就要放到研究vivi源代码上面了。我想,真正细致地弄清楚vivi实现的细节,对C语言水平的提高,对ARM体系结构的认识,对S3C2410的熟悉,对嵌入式bootloader相关技术,都能有很大的好处。学习的进度会慢一些,但是务求深入,并且打好相关的基础。 一、写在前

menuconfig的专栏 2172

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

vivi源代码最为详细分析(三)

step 5:     MTD设备初始化。     关于什么是MTD,为什么要使用MTD,MTD技术的架构是什么,等等,可以参考《Linux MTD源代码分析》(作者:Jim Zeus,2002-04-29)。这份文档的参考价值比较大,猜想作者在当时可能研究了很长时间,毕竟2002年的时候资料还比较缺乏。当然,因为完全分析透彻,方方面面都点透,这份文档还是没有做到。      在分析代码前先介绍一下MTD(Memory Technology Device)相关的技术。在inux系统中,我们通常会用到不同的存

liangkaiming的专栏 4181

vivi源代码最为详细分析(一)

<br />通过vivi研究bootloader有一段时间了,基本是在与之相关的基础方面做工作,还没有真正深入研究vivi。以后的学习重心就要放到研究vivi源代码上面了。我想,真正细致地弄清楚vivi实现的细节,对C语言水平的提高,对ARM体系结构的认识,对S3C2410的熟悉,对嵌入式bootloader相关技术,都能有很大的好处。学习的进度会慢一些,但是务求深入,并且打好相关的基础。 一、写在前面的话<br />    嵌入式系统软件开发主要包括五个方面:bootloader编写(移植)、驱动程序编写

liangkaiming的专栏 8547

VIVI讲解与分析

Vivi 是韩国mizi 公司开发的bootloader, 适用于ARM9处理器。 Vivi有两种工作模式:启动加载模式和下载模式。启动加载模式可以在一段时间后(这个时间可更改)自行启动linux内核,这时vivi的默认模式。在下载模式下,vivi为用户提供一个命令行接口,通过接口可以使用vivi提供的一些命令,见下表: 

LEA的专栏 1896

vivi源代码最为详细分析(二)

现在进入bootloader之vivi分析的第二阶段,这部分使用C语言实现,部分代码采取内嵌汇编的方式。这里需要用到GNU GCC内嵌汇编的知识,这部分基础还没有具备,需要学习。     下面先按照流程进行分析。需要注意的是,此部分内容并非完全按照原版的vivi源代码,而是加入了自己的理解。另外,对非常简单、google出一片而且有分析正确的部分,在这里就简化了,不做详细分析,只是对网上没有分析到位而又影响理解的部分进行深入分析。我想,这部分内容应该是对《s3c2410完全开发》中vivi源代码分析部分的补

liangkaiming的专栏 4276
上一篇: Linux 下 C 语言编程
下一篇: uC/OS-II 中文手册
menuconfig
博客等级 码龄19年 713粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值