在移植u-boot之前,可以参考我之前的博客移植操作一遍,理解一下ARM-LINUX的启动流程:bootloader->linux内核->文件系统->应用程序。最重要的一点,移植u-boot一定要耐心、细心,因为u-boot涉及到开发板cpu的时钟配置、内存初始化等等软硬件环境的配置。

一、

1.我们的FL2440开发板移植u-boot以smdk2410为母板进行移植,所以用smdk2410创建配置文件;

2.修改顶层makefile,定义交叉编译工具链,然后定义开发板配置选项,我们用的u-boot-2010.09是在boards.cfg中配置的:

3、就是u-boot启动代码的修改了,主要是修改start.S、lowlevel_init.S

4.板子外设驱动添加,这里我们主要添加的是DM9000网卡的支持;

5.nand flash启动代码修改,支持nandflash启动;

二、

指定你的linux操作系统下的交叉编译器的路径,用于编译整个u-boot


三、

在u-boot顶层makefile文件中添加交叉编译器的路径

vim Makefile

vim boards.cfg

smdk2410 arm arm920t - samsung s3c24x0

fl2440 arm arm920t fl2440 lingyun s3c24x0

make fl2440_config

make

生成.bin文件  u-boot.bin

四、

start.S 修改

vim arch/arm/cpu/arm920t/start.S

下面这两行代码是 AT91RM9200DK这个开发板才有的代码,所以我们应该把他注释掉。汇编中@
表示单行注释,在 GNU 的汇编中,也支持 C 代码中的各种注释。
@bl coloured_LED_init
@bl red_LED_on

# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
#elif defined CONFIG_S3C2440(添加该代码对于S3C2440 CPU向其中写入0x7fff 就是将 INTSUBMSK
寄存器全部有效位(低 15 位)置 1,从而屏蔽对应的中断。 )
ldr r1, =0x7fff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif

添加S3C2440汇编初始化 LED 和 CPU时钟的代码
# if defined(CONFIG_S3C2440)
#define GPBCON 0x56000010
#define GPBDAT 0x56000014
#define GPBUP 0x56000018
/*Set GPIO5, GPIO6, GPIO8, GPIO10 as GPIO OUTPUT mode*/(对灯进行初始化)
ldr r0, =GPBCON
ldr r1, [r0]
bic r1, r1, #0x3c00 /*Set GPBCON for GPIO5,GPIO6 as 0x00 */
orr r1, r1, #0x1400 /*Set GPBCON for GPIO5,GPIO6 as GPIOOUT, 0x01*/
bic r1, r1, #0x00330000 /*Set GPBCON for GPIO8,GPIO10 as 0x00*/
orr r1, r1, #0x00110000 /*Set GPBCON for GPIO8,GPIO10 as GPIOOUT, 0x01*/
str r1, [r0]
/*Set internal pullup resister*/
ldr r0, =GPBUP
ldr r1, [r0]
orr r1, r1, #0x0560 /*Set bit 5,6,8,10, disable pullup resister*/
str r1, [r0]
ldr r2, =GPBDAT
ldr r3, [r2]
orr r3, r3, #0x0560 /*Set bit 5,6,8,10 as high level, Turn Off LED*/(把所有等设置为灭)可以利用等的亮灭来提示u-boot进行到哪一个步骤,相当于自己加一个debug
str r3, [r2]

# define MPLLCON 0x4C000004
# define MDIV_405 0x7f << 12
# define PSDIV_405 0x21
/* FCLK:HCLK:PCLK = 1:4:8 */
ldr r0, =CLKDIVN /*把CLKDIVN寄存器地址存入 R0 中*/
mov r1, #0x05 /*把立即数5存入寄存器 R1中*/
str r1, [r0] /*把寄存器R1的值(即5)存入到R0所指向的地址中(即CLKDIVN寄存器的
地址)*/

mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000 /* 修改CPU总线模式为"asynchronous bus mode" */
mcr p15, 0, r1, c1, c0, 0
Ldr r0,=MPLLCON /*把MPLLCON寄存器地址存入 R1 中*/
mov r1, #MDIV_405 /*把常量MDIV_405存入寄存器 R2 中*/
add r1, r1, #PSDIV_405 /*r2=MDIV_405+PSDIV_405*/
str r1, [r0] /*把R2的值写入 MPLLCON寄存器中*/
#else /*S3C2410, S3C2440 */
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif /* end of if defined(CONFIG_S3C2440)

relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM 将0x33f80000写入 r1 寄存器*/
cmp r0, r1 /* don't reloc during debug 比较 r0 和 r1寄存器的值*/
beq stack_setup

judgment_norflash_nandflash_boot:
ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* 0x4000003C 地址(S3C24x0内部SRAM)写入r1寄存器*/
mov r0, #0 /* 将立即数 0x0写入r0 寄存器*/
str r0, [r1] /*将 r0的值写入r1 存放的内存地址中去,即把0x4000 003C地址修改为0 */
mov r1, #0x3c /* 把地址 0x0000003C 写入到 r1寄存器*/
ldr r0, [r1] /* 将 r1所存放的内存单元(0x0000003C)的值装入r0中*/
cmp r0, #0 /* r0 的值(即0x0000003C的值)与0比较 */
bne norflash_boot
nandflash_boot:
#define LENGTH_UBOOT 0x60000 定义从Nandflash拷贝u-boot的长度
#define NAND_CTL_BASE 0x4E000000 Nandflash控制器一系列寄存器的基地址
/* Offset */
#define oNFCONF 0x00 NFCONF 寄存器相对于NAND_CTRL_BASE的偏移值,下类似
#define oNFCONT 0x04
#define oNFCMD 0x08
#define oNFSTAT 0x20
mov r1, #NAND_CTL_BASE
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
str r2, [r1, #oNFCONT]
ldr r2, [r1, #oNFCONT]
ldr r2, =(0x6) @ RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
重启 Nandflash 后,用循环用来等待一段时间
mov r3, #0 @ wait
nand_delay:
add r3, r3, #0x1
cmp r3, #0xa
blt nand_delay
通过读 Nandflash 控制器的 NFSTAT 寄存器中bit2来判断 Nandflash是否Ready
nand_wait:
ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x4
beq nand_wait
通过设置 NFCONT 寄存器的 bit1 来Disable Chip Select
ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 @ Flash Memory Chip Disable
str r2, [r1, #oNFCONT]
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
ldr r0, =TEXT_BASE nand_read_ll()第一个参数buf指向 0x33f80000,这就是u-boot拷贝的目标地址
mov r1, #0x0 nand_read_ll()第二个参数start_addr指向 0,即从nandflash的 0 地址开始拷贝
mov r2, #LENGTH_UBOOT nand_read_ll()第三个参数size为要拷贝的 u-boot 的大小
bl nand_read_ll 调用nand_read_ll()函数
tst r0, #0x0 判断 nand_read_ll()函数的返回值是否为 0
beq ok_nand_read
bad_nand_read:
dead_loop:
b dead_loop @ infinite loop
ok_nand_read:
@ verify
mov r0, #0 CPU 片内4K SRAM的起始地址为 0,启动时硬件自动拷贝u-boot前 4K到这里
ldr r1, =TEXT_BASE SDRAM内存中地址0x33F80000,刚才的nand_read_ll()搬移u-boot 到这里
mov r2, #0x400 0x400 = 1K-bytes,下面一下子比较4个字节,所以总共比较 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4 4 个字节处开始比较,如果不相同则跳到notmatch处,程序死循环。
bne notmatch
subs r2, r2, #4 如果相等,就看是否已比较完
beq stack_setup 如果比较完,说明搬运OK。这时开始跳到堆栈处初始化堆栈开始执行C代码
bne go_next 如果没有比较完,就继续下一次比较
notmatch: 如果某个字节不匹配则在程序在这里死掉
infinite_loop:
b infinite_loop @ infinite loop
norflash_boot:
这段代码用来计算要搬运的 u-boot 代码的起始地址和结束地址

。。。。。。略
start_armboot: .word start_armboot
#ifdef CONFIG_S3C24X0
#define STACK_BASE 0x33f00000 在调用 nand_read_ll()函数之前设置的临时堆栈地址和大小
#define STACK_SIZE 0x10000
.align 2
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
#endif

五、

lowlevel_init.S 修改

/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable 使能刷新 */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh 设置为自动刷新*/
#if defined(CONFIG_S3C2440)
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable 使能刷新 */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh 设置为自动刷新*/
#if defined(CONFIG_S3C2440)
#define REFCNT 1268
#else
#define Trp 0x0 /* 2clk */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
#endif 
TEXT_BASE:
.word TEXT_BASE
这里相当于定义一个全局的 lowlevel_init函数,在start.S 中会调用它
.globl lowlevel_init
lowlevel_init:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
将 SMDATA 地址(13个寄存器的值存放在内存中的起始地址0x33F8xxxx)加载到r0
ldr r0, =SMRDATA
将 lowlevel_init 的地址加载到 r1 寄存器中
ldr r1, =lowlevel_init
r0 减去 r1的结果存入r0,也即SMDATA相对于 lowlevel_inti的偏移地址
sub r0, r0, r1
获取 lowlevel_init 在内存中的实际地址
adr r3, lowlevel_init /* r3 <- current position of code */
运行时 lowlevel_init在内存中的地址加上SMDATA 相对于它的偏移,就获取到了SMDATA 在内存中的实际地址
add r0, r0, r3
六、
添加从 nandflash拷贝U-boot 到 SDRAM中去的SDRAM 的C代码源文件 nand_read.c ,篇幅所限这里的代码略了。。。
修改 board/lingyun/fl2440/Makefile,添加nand_read.c文件的编译支持
vim board/lingyun/fl2440/Makefile
COBJS := fl2440.o nand_read.oflash.o
.....
修改 u-boot链接文件arch/arm/cpu/arm920t/u-boot.lds
vim arch/arm/cpu/arm920t/u-boot.lds
text :
{
arch/arm/cpu/arm920t/start.o (.text)
board/lingyun/fl2440/lowlevel_init.o (.text)
board/lingyun/fl2440/nand_read.o (.text)
*(.text)
}
七、添加 CONFIG_S3C2440条件编译

vim include/configs/fl2440.h
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_S3C24X0 1 /* in a SAMSUNG S3C24x0-type SoC */
将 CONFIG_S3C2410 改成 CONFIG_S3C2440,因为我们用的是S3C2440这颗 CPU
#define CONFIG_S3C2440 1 /* specifically a SAMSUNG S3C2440 SoC */
将 CONFIG_SMDK2410改成CONFIG_FL2440
#define CONFIG_FL2440 1 /* FL2440 board */

vim include/serial.h 
.................

#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
extern struct serial_device s3c24xx_serial0_device;
extern struct serial_device s3c24xx_serial1_device;
extern struct serial_device s3c24xx_serial2_device;
#endif

vim common/serial.c
...............

#if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
serial_register(&s3c24xx_serial0_device);
serial_register(&s3c24xx_serial1_device);
serial_register(&s3c24xx_serial2_device);
#endif

...............

#elif defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
#if defined(CONFIG_SERIAL1)

...................
vim arch/arm/include/asm/arch-s3c24x0/s3c24x0_cpu.h
#ifdef CONFIG_S3C2400
#include <asm/arch/s3c2400.h>
#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
..............

vim arch/arm/include/asm/arch-s3c24x0/s3c24x0.h
struct s3c24x0_interrupt {
u32 SRCPND;
u32 INTMOD;
u32 INTMSK;
u32 PRIORITY;
u32 INTPND;
u32 INTOFFSET;
S3C2440 CPU 的中断寄存器地址和S3C2410完全一样
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
........

struct s3c24x0_dma {
u32 DISRC;
s3c2440 CPU 的 DMA 寄存器地址和 S3C2410的也完全一样
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
u32 DISRCC;
#endif
u32 DIDST;
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
........
#ifdef CONFIG_S3C2400
u32 res[1];
#endif
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
u32 res[7];
#endif
}; 
.........

struct s3c24x0_clock_power {
u32 LOCKTIME;
u32 MPLLCON;
u32 UPLLCON;
u32 CLKCON;
u32 CLKSLOW;
u32 CLKDIVN;
S3C2440 比 S3C2410 CPU 多了摄像头接口,在时钟管理相关的寄存器中也多了这个摄像头的部分
#if defined (CONFIG_S3C2440)
u32 CAMDIVN;
#endif
};

#if defined(CONFIG_S3C2410)
struct s3c2410_nand {
u32 NFCONF;
u32 NFCMD;
u32 NFADDR;
u32 NFDATA;
u32 NFSTAT;
u32 NFECC;
};
#elif defined (CONFIG_S3C2440)
struct s3c2410_nand {
u32 NFCONF;
u32 NFCONT;
u32 NFCMD;
u32 NFADDR;
u32 NFDATA;
u32 NFMECCD0;
u32 NFMECCD1;
u32 NFSECCD;
u32 NFSTAT;
u32 NFESTAT0;
u32 NFESTAT1;
u32 NFMECC0;
u32 NFMECC1;
u32 NFSECC;
u32 NFSBLK;
u32 NFEBLK;
};
#endif
...  ...
struct s3c24x0_gpio {
#ifdef CONFIG_S3C2400
......
u32 MISCCR;
u32 EXTINT;
S3C2440 GPIO 口寄存器前面部分的地址和 S3C2410 的完全一样,但前者比后者要多出一些寄存器
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

#if defined (CONFIG_S3C2440)
u32 res9[3];
u32 MSLCON;
u32 GPJCON;
u32 GPJDAT;
u32 GPJUP;
#endif
#endif
};

vim arch/arm/cpu/arm920t/s3c24x0/timer.c
.........
vim arch/arm/cpu/arm920t/s3c24x0/speed.c
...........
m = ((r & 0xFF000) >> 12) + 8;
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;
这里 S3C2440 的 PLL 时钟和S3C2410的不一样
#if defined(CONFIG_S3C2440)
if (pllreg == MPLL)
return ((CONFIG_SYS_CLK_FREQ * m * 2) /(p << s));
else if (pllreg == UPLL)
#endif
ulong get_HCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
S3C2440 根据 CLKDIV 寄存器的值来返回 HCLK的频率
#if defined(CONFIG_S3C2440)
if (readl(&clk_power->CLKDIVN) & 0x6)
{
if ((readl(&clk_power->CLKDIVN) & 0x6)==2)
return(get_FCLK()/2);
if ((readl(&clk_power->CLKDIVN) & 0x6)==6)
return((readl(&clk_power->CAMDIVN) & 0x100) ? get_FCLK()/6 :
get_FCLK()/3);
if ((readl(&clk_power->CLKDIVN) & 0x6)==4)
return((readl(&clk_power->CAMDIVN) & 0x200) ? get_FCLK()/8 :
get_FCLK()/4);
return(get_FCLK());
}
else
return(get_FCLK());
#else
return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();
#endif
}
八、
添加网络支持
vim include/configs/fl2440.h
#if 0 禁用 CS89000网卡
#define CONFIG_NET_MULTI
#define CONFIG_CS8900 /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x19000300
#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
#else 添加 DM9000网卡
#define CONFIG_NET_MULTI 1
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000300 /* nGCS4 */
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_DM9000_NO_SROM 1
#undef CONFIG_DM9000_DEBUG
#endif
... ...
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
#define CONFIG_CMD_PING 添加ping命令支持
我们可以在这里修改 CONFIG_BOOTDELAY 来改变启动时按任意键进入debug模式的延时时间
#define CONFIG_BOOTDELAY 2
/*#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,9600" */
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b 配置网卡的MAC地址
#define CONFIG_NETMASK 255.255.255.0 配置网络子网掩码
#define CONFIG_IPADDR 192.168.1.168 配置网卡IP地址
#define CONFIG_SERVERIP 192.168.1.2 配置TFTP服务器 IP地址
/*#define CONFIG_BOOTFILE "elinos-lart" */
/*#define CONFIG_BOOTCOMMAND "tftp; bootm" */
...  ...
我们可以在这里通过修改 CONFIG_SYS_PROMPT来修改u-boot 的命令提示符
#define CONFIG_SYS_PROMPT "[fl2440@lingyun]# " /* Monitor Command Prompt */ 
vim board/lingyun/fl2440/fl2440.c 从(初始化DM9000网卡)
#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_CS8900
rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
#ifdef CONFIG_DRIVER_DM9000
rc = dm9000_initialize(bis);
#endif
return rc;
}
#endif
九、添加nand flash支持
略.......
到了这里整个u-boot移植就告一段落
问题及解决方法:
1,不能自启动judgment 代码没写在patch文档150行左右
2,删除了宏定义,对照文档修改
3,环境变量设置有问题,要根据自己的系统来修改
关键是细心、细心、细心,重要的事情说三遍,欢迎大家和我讨论,我对u-boot移植也有点一知半解,参考郭工的文档,做了一个多星期。总算是完成了。

fl2440u-boot移植相关推荐

  1. 【u-boot】uboot代码简要分析 (u-boot 移植)

    uboot代码简要分析 (u-boot 移植) 2012-12-19 22:46:04 [转] 先来看看源码目录结构,再按照代码的执行顺序简单地分析源码 1.U-boot源码整体框架 源码解压以后,我 ...

  2. uboot移植之修改支持NandFlash识别篇6(超详细)

    uboot移植之前期准备篇1 uboot移植之Makefile分析概述篇2 boot移植之init_sequence_f函数数组分析(番外篇) uboot移植之源码流程分析篇3(超详细!) uboot ...

  3. RT_thread STM32通用Bootloader 做OTA升级

    项目上需要做设备的远程升级更新程序,从而避免每次更新程序时都需要去现场烧录的麻烦.从而学习探索了RT提供的OTA功能. RT-Thread 开发团队提供了通用的 Bootloader.开发者通过该 B ...

  4. U-boot中控制台命令

    u-boot学习笔记如下: 用j-link commder 烧写nand flash(只能借助sdram来间接烧写) nand flash启动时候,我们接着s3c2440芯片内部的sram来烧写. r ...

  5. 【单片机开发】stm32f429在线IAP 实现SD卡烧写程序

    (一)背景介绍 最近做了一个工程需要用到IAP在线升级这个功能,当时在学的时候,了解到IAP的功能当时就觉得很鸡肋,明明有烧写器干嘛那么费事,现在觉得当时确实浅薄了,IAP功能在工程中确实是非常有用的 ...

  6. 移植U-Boot.1.3.1到S3C2440和S3C2410

    原文链接:[url]http://blog.chinaunix.net/u1/34474/showart.php?id=487416[/url] 首先,U-Boot1.3.1还没有支持s3c2440, ...

  7. 移植 u-boot-2020.07 到 iTOP-4412(二)地址相关码 boot

    文章目录 前言 一.重新编写脚本 1. init_env.sh 2. build.sh 3. sdflush.sh 二.spl 启动流程 1. start.S 2. board_init_f() 2. ...

  8. 移植U-Boot.1.3.1到S3C244和S3C2410

    移植U-Boot.1.3.1到S3C244和S3C2410 首先,U-Boot1.3.1还没有支持s3c2440,移植仍是用2410的文件稍作修改而成的.2440和2410的区别在我移植1.2.0的文 ...

  9. u-boot-1.3.4移植到mini2440+128M nand boot(3)

    第4阶段 修改适合S3C2440的程序 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office ...

  10. linux mpc boot 串口初始化,uboot移植阶段二--3串口终结篇

    2011-03-20 23:00:37 前天U-boot移植串口后,能成功显示数据. 今天的主要目的是再次进行U-boot移植.看是否成功.花了40分钟,很顺利. 接着就是要把之前有问题的U-boot ...

最新文章

  1. xdebug怎样在php中配置,教你在PHPStorm中配置Xdebug
  2. 如何使用 React 创建一个作品集网站
  3. JavaScript直接导出Excel,Word
  4. Android样式开发--selector
  5. Week_1_Physical Electronics and Semiconductors
  6. LeetCode 1717. 删除子字符串的最大得分
  7. 从省市区多重级联想到的,react和jquery的差别
  8. 《编程之美》3.6判断链表是否相交之扩展:链表找环方法证明
  9. Interesting Finds: 2008.04.18
  10. 德尔福和Mobileye强强联手,将展示双方共同开发的CSLP系统
  11. 原子结构示意图全部_原子结构示意图全部-原子结构示意图规律口诀-前20号元素的原子结构示意图...
  12. event mpm php,Apache下三种MPM模式:prefork,worker和event
  13. 「开发者说」钉钉连接器+OA审批实现学校学生假勤场景数字化
  14. win10的Pytorch最全安装教程,解决pytorch安装问题!
  15. 儿子考上清华大学计算机系视频,儿子考上清华大学,家长忙发朋友圈,但收到的却不是祝福是心寒...
  16. C/C++数据结构——最优屏障(栈)
  17. 游戏服务器主程白皮书-序言
  18. phpcms 添加顶踩功能
  19. 数学模型4.8例1投资组合lingo,matlab
  20. Java中什么是JRE?什么是JRE?

热门文章

  1. 硅谷职场“神女”记:谷歌Twitter随便跳(图)
  2. easy_crypto
  3. Linux安装nginx并配置ssl
  4. 2021黄山高考成绩查询,2021黄山市地区高考成绩排名查询,黄山市高考各高中成绩喜报榜单...
  5. windows - 服务器重启原因排查
  6. 今日芯声 | 理想汽车在美上市首日暴涨 43%,总市值近 140 亿美元
  7. 搭建一个页面并备份用户上传的文件项目作业
  8. jsp生成Word文件!最直接方式!
  9. (17)网络安全:cookie注入、二次注入、DNSlog注入、中转注入、堆叠注入的原理及注入过程
  10. 新主板别再买SATA SSD了,NVMe M.2爽多了