我的BL1源代码来源于网路,博客地址是http://blog.csdn.net/xiaojiaohuazi/article/details/8265757。在这里记录下自己的移植心得。

为什么要制作这个BL1呢,对于官方以及很多人说的它是u-boot启动的第二阶段,这里我不做过多说明,我想说的是,这个BL1可以让你对内存操作的理解更加深入,对于后面移植u-boot的理解有帮助。

实际上在BL1阶段只需要做串口和内存的初始化就可以了,初始化串口的目的是调试使用,这个是必须要的;初始化内存那不用说了,你想拷贝代码,不初始化内存怎么能行的。

但是在这里我还加入了一个LED的操作代码,为什么要加入呢,对于学习一个东西,不能说会移植了就算学会了,我想有问题的时候会调试才是更重要的,在开发时也是如此,有了调试手段就有了查错的手段,那么找问题就可以很方便的定位了。所以加入这个LED的控制目的也就是为了调试使用,这也是看到网上有人说过,仔细想想,非常好用,O(∩_∩)O。

首先看看我的BL1的所有文件:

这里只说明移植的时候涉及到的文件,build、main.c、mem_setup.S、s5pv210.h、start.S这几个文件。其中build是我加入的一个文件,目的在操作编译烧写的时候减少输入命令,build文件的内容如下:

#!/bin/sh
make
./mkv210_image bl.bin blSD2.bin
dd iflag=dsync oflag=dsync if=blSD2.bin of=/dev/sdc seek=1

做的工作就是编译,制作BL1,烧写到SD卡。

这个BL1启动的入口也是在start.S文件,看看做的是什么:

.text.global _start_start:bl mem_ctrl_asm_initldr sp, =0xD0035400bl mainloop:b loop

第一步就是初始化内存也就是进入mem_ctrl_asm_init这个函数进行执行,这个函数的代码如下:

mem_ctrl_asm_init:/* DMC0 Drive Strength (Setting 2X) */ldr  r0, =ELFIN_GPIO_BASEldr    r1, =0x0000AAAAstr r1, [r0, #MP1_0DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP1_1DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP1_2DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP1_3DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP1_4DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP1_5DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP1_6DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP1_7DRV_SR_OFFSET]ldr    r1, =0x00002AAAstr r1, [r0, #MP1_8DRV_SR_OFFSET]/* DMC1 Drive Strength (Setting 2X) */ldr  r0, =ELFIN_GPIO_BASEldr    r1, =0x0000AAAAstr r1, [r0, #MP2_0DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP2_1DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP2_2DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP2_3DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP2_4DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP2_5DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP2_6DRV_SR_OFFSET]ldr    r1, =0x0000AAAAstr r1, [r0, #MP2_7DRV_SR_OFFSET]ldr    r1, =0x00002AAAstr r1, [r0, #MP2_8DRV_SR_OFFSET]/* DMC0 initialization at single Type*/ldr r0, =APB_DMC_0_BASEldr r1, =0x00101000                @PhyControl0 DLL parameter setting, manual 0x00101000str   r1, [r0, #DMC_PHYCONTROL0]ldr   r1, =0x00000086                @PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Casestr   r1, [r0, #DMC_PHYCONTROL1]ldr   r1, =0x00101002                @PhyControl0 DLL onstr r1, [r0, #DMC_PHYCONTROL0]ldr   r1, =0x00101003                @PhyControl0 DLL startstr  r1, [r0, #DMC_PHYCONTROL0]find_lock_val:ldr r1, [r0, #DMC_PHYSTATUS]        @Load Phystatus register valueand  r2, r1, #0x7cmp r2, #0x7                @Loop until DLL is lockedbne   find_lock_valand    r1, #0x3fc0 mov r2, r1, LSL #18orr  r2, r2, #0x100000orr    r2 ,r2, #0x1000 orr r1, r2, #0x3                @Force Value lockingstr    r1, [r0, #DMC_PHYCONTROL0]#if 0 /* Memory margin test 10.01.05 */orr    r1, r2, #0x1                @DLL offstr    r1, [r0, #DMC_PHYCONTROL0]
#endif/* setting DDR2 */ldr r1, =0x0FFF2010                @ConControl auto refresh offstr    r1, [r0, #DMC_CONCONTROL]ldr    r1, =DMC0_MEMCONTROL           @MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down offstr r1, [r0, #DMC_MEMCONTROL]ldr    r1, =DMC0_MEMCONFIG_0          @MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixedstr    r1, [r0, #DMC_MEMCONFIG0]ldr    r1, =DMC0_MEMCONFIG_1          @MemConfig1str r1, [r0, #DMC_MEMCONFIG1]ldr    r1, =0xFF000000                @PrechConfigstr    r1, [r0, #DMC_PRECHCONFIG]ldr   r1, =DMC0_TIMINGA_REF          @TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)str r1, [r0, #DMC_TIMINGAREF]ldr    r1, =DMC0_TIMING_ROW           @TimingRow for @200MHzstr r1, [r0, #DMC_TIMINGROW]ldr r1, =DMC0_TIMING_DATA          @TimingData    CL=3str    r1, [r0, #DMC_TIMINGDATA]ldr    r1, =DMC0_TIMING_PWR           @TimingPowerstr    r1, [r0, #DMC_TIMINGPOWER]ldr   r1, =0x07000000                @DirectCmd chip0 Deselectstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01000000                @DirectCmd chip0 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00020000                @DirectCmd chip0 EMRS2str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00030000                @DirectCmd chip0 EMRS3str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010400                @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00000542                @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01000000                @DirectCmd chip0 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05000000                @DirectCmd chip0 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05000000                @DirectCmd chip0 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00000442                @DirectCmd chip0 MRS (MEM DLL unreset)str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010780                @DirectCmd chip0 EMRS1 (OCD default)str    r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010400                @DirectCmd chip0 EMRS1 (OCD exit)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x07100000                @DirectCmd chip1 Deselectstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01100000                @DirectCmd chip1 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00120000                @DirectCmd chip1 EMRS2str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00130000                @DirectCmd chip1 EMRS3str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110400                @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00100542                @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01100000                @DirectCmd chip1 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05100000                @DirectCmd chip1 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05100000                @DirectCmd chip1 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00100442                @DirectCmd chip1 MRS (MEM DLL unreset)str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110780                @DirectCmd chip1 EMRS1 (OCD default)str    r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110400                @DirectCmd chip1 EMRS1 (OCD exit)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x0FF02030                @ConControl    auto refresh onstr  r1, [r0, #DMC_CONCONTROL]ldr    r1, =0xFFFF00FF                @PwrdnConfigstr    r1, [r0, #DMC_PWRDNCONFIG]ldr   r1, =DMC0_MEMCONTROL               @MemControl 0x00202400     BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down offstr  r1, [r0, #DMC_MEMCONTROL]/* DMC1 initialization */ldr   r0, =APB_DMC_1_BASEldr r1, =0x00101000                @Phycontrol0 DLL parameter settingstr  r1, [r0, #DMC_PHYCONTROL0]ldr   r1, =0x00000086                @Phycontrol1 DLL parameter settingstr  r1, [r0, #DMC_PHYCONTROL1]ldr   r1, =0x00101002                @PhyControl0 DLL onstr r1, [r0, #DMC_PHYCONTROL0]ldr   r1, =0x00101003                @PhyControl0 DLL startstr  r1, [r0, #DMC_PHYCONTROL0]
find_lock_val1:ldr  r1, [r0, #DMC_PHYSTATUS]        @Load Phystatus register valueand  r2, r1, #0x7cmp r2, #0x7                @Loop until DLL is lockedbne   find_lock_val1and   r1, #0x3fc0 mov r2, r1, LSL #18orr  r2, r2, #0x100000orr    r2, r2, #0x1000orr  r1, r2, #0x3                @Force Value lockingstr    r1, [r0, #DMC_PHYCONTROL0]#if 0 /* Memory margin test 10.01.05 */orr    r1, r2, #0x1                @DLL offstr    r1, [r0, #DMC_PHYCONTROL0]
#endif/* settinf fot DDR2 */ldr r0, =APB_DMC_1_BASEldr r1, =0x0FFF2010                @auto refresh offstr   r1, [r0, #DMC_CONCONTROL]ldr    r1, =DMC1_MEMCONTROL           @MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down offstr  r1, [r0, #DMC_MEMCONTROL]ldr    r1, =DMC1_MEMCONFIG_0          @MemConfig0    512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixedstr r1, [r0, #DMC_MEMCONFIG0]ldr    r1, =DMC1_MEMCONFIG_1          @MemConfig1str r1, [r0, #DMC_MEMCONFIG1]ldr    r1, =0xFF000000str r1, [r0, #DMC_PRECHCONFIG]ldr   r1, =DMC1_TIMINGA_REF          @TimingAref    7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4str   r1, [r0, #DMC_TIMINGAREF]ldr    r1, =DMC1_TIMING_ROW           @TimingRow for @200MHzstr r1, [r0, #DMC_TIMINGROW]ldr r1, =DMC1_TIMING_DATA          @TimingData    CL=3str    r1, [r0, #DMC_TIMINGDATA]ldr    r1, =DMC1_TIMING_PWR           @TimingPowerstr    r1, [r0, #DMC_TIMINGPOWER]ldr   r1, =0x07000000                @DirectCmd chip0 Deselectstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01000000                @DirectCmd chip0 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00020000                @DirectCmd chip0 EMRS2str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00030000                @DirectCmd chip0 EMRS3str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010400                @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00000542                @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01000000                @DirectCmd chip0 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05000000                @DirectCmd chip0 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05000000                @DirectCmd chip0 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00000442                @DirectCmd chip0 MRS (MEM DLL unreset)str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010780                @DirectCmd chip0 EMRS1 (OCD default)str    r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00010400                @DirectCmd chip0 EMRS1 (OCD exit)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x07100000                @DirectCmd chip1 Deselectstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01100000                @DirectCmd chip1 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00120000                @DirectCmd chip1 EMRS2str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00130000                @DirectCmd chip1 EMRS3str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110440                @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00100542                @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x01100000                @DirectCmd chip1 PALLstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05100000                @DirectCmd chip1 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x05100000                @DirectCmd chip1 REFAstr   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00100442                @DirectCmd chip1 MRS (MEM DLL unreset)str  r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110780                @DirectCmd chip1 EMRS1 (OCD default)str    r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x00110400                @DirectCmd chip1 EMRS1 (OCD exit)str   r1, [r0, #DMC_DIRECTCMD]ldr r1, =0x0FF02030                @ConControl    auto refresh onstr  r1, [r0, #DMC_CONCONTROL]ldr    r1, =0xFFFF00FF                @PwrdnConfig   str r1, [r0, #DMC_PWRDNCONFIG]ldr   r1, =DMC1_MEMCONTROL           @MemControl    BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down offstr  r1, [r0, #DMC_MEMCONTROL]//下面为点灯代码,用于调试ldr r0, =0xE0200C00  ldr r1, =0x11000000  str r1, [r0]  ldr r1, =0xc0  str r1, [r0, #4]//上面为点灯代码,用于调试   mov pc, lr

可以看到我在该函数的最后增加了LED灯的代码,具体的含义请参考帖子 http://blog.csdn.net/kevinshq/article/details/7968409不同的板子LED接口可能不同,这样的话就需要修改寄存器的地址了,也可能没有LED,如果是这种情况就需要使用其他的提醒功能来代替LED了(最好是能够看到现象的)。LED代码放在这里在启动板子的时候就可以观察LED的状态来判断内存初始化这部分代码是否启动了。

好,现在回到该函数的起始部分,对于该函数已经有人做过了分析,这里我就引用之博文地址为http://blog.csdn.net/mutemob/article/details/12974483。在这之外我们需要注意一个问题,那就是下面代码的位置处

有可能你的代码红色部分为0x00202400这种格式的16进制,最好是改成上图所示的请款个,目的是为了方便修改。

从start.S文件中可以知道,第二个执行的函数为main函数,函数位置在main.c。

main.c文件源代码请下载下来观看,这里我就不一次全部贴上来了。我们从main主函数出发,看看都做了些什么:

int main (void)
{__attribute__((noreturn)) void (*uboot)(void); uart_init(); //串口初始化mem_test(); //内存测试printf ("copy uboot from sd to sdram ddr2\r\n"); copy_uboot_to_ram(); printf ("jump to u-boot image\r\n"); //下面代码是控制班子上的LED,可用于调试 //*(volatile unsigned int *)0xE0200C00 = 0x11000000;  //*(volatile unsigned int *)0xE0200C04 = 0x000000c0; //上面代码是控制班子上的LED,可用于调试 /* Jump to U-Boot imaguboot = (void *)0x33e00000; (*uboot)(); return 1;
}

开始进行了串口的初始化,然后是内存的测试,接着是u-boot的拷贝阶段,最后跳转到u-boot的位置开始执行。我的u-boot的起始地址是0x33e00000,不同的板子地址可能有所不同,请调整为自己的u-boot起始地址即可,也就是把0x33e00000换成自己的板子的地址。

串口的初始化我的板子是Real210板子,调试口使用的是串口2,所以在网络上原来的代码基础上把他的串口初始化从串口0修改到了串口2,在源码的s5pv210.h中可以看到各寄存器的定义。串口的初始化是在文件uart.c中进行,这里我不再说明,具体的请参阅s5pv210 pdf进行对比学习。

内存的测试函数mem_test()代码如下:

void mem_test()
{#define test_mem1 0x30000000#define test_mem2 0x33e00004#define test_mem3 0x3f000f08#define test_mem4 0x3ffff0fc#define test_mem5 0x3ffffffc   //内存地址是每隔4个字节存放的,所以访问时是4个字节访问#define test_mem6 0x40000000#define test_mem7 0x43e00004#define test_mem8 0x4f00f008#define test_mem9 0x4ffffff8   #define test_mem10 0x4ffffffcunsigned int *p1 = (volatile unsigned int *)test_mem1;unsigned int *p2 = (volatile unsigned int *)test_mem2;unsigned int *p3 = (volatile unsigned int *)test_mem3;unsigned int *p4 = (volatile unsigned int *)test_mem4;unsigned int *p5 = (volatile unsigned int *)test_mem5;unsigned int *p6 = (volatile unsigned int *)test_mem6;unsigned int *p7 = (volatile unsigned int *)test_mem7;unsigned int *p8 = (volatile unsigned int *)test_mem8;unsigned int *p9 = (volatile unsigned int *)test_mem9;unsigned int *p10 = (volatile unsigned int *)test_mem10;printf ("******s5pv210 Test********\r\n");printf ("********By ZheGao********\r\n");*p1 = 0x12345678;if (*p1 == 0x12345678) {printf ("1: equ\r\n");} else {printf ("1: not equ\r\n");}*p2 = 0x12345678;if (*p2 == 0x12345678) {printf ("2: equ\r\n");} else {printf ("2: not equ\r\n");}*p3= 0xfffffff0;if (*p3 == 0xfffffff0) {printf ("3: equ\r\n");} else {printf ("3: not equ\r\n");}*p4 = 0x12345678;if (*p4 == 0x12345678) {printf ("4: equ\r\n");} else {printf ("4: not equ\r\n");}*p5 = 0x12345678;if (*p5 == 0x12345678) {printf ("5: equ\r\n");} else {printf ("5: not equ\r\n");}*p6= 0xfffffff0;if (*p6 == 0xfffffff0) {printf ("6: equ\r\n");} else {printf ("6: not equ\r\n");}*p7 = 0x12345678;if (*p7 == 0x12345678) {printf ("7: equ\r\n");} else {printf ("7: not equ\r\n");}*p8 = 0x12345678;if (*p8 == 0x12345678) {printf ("8: equ\r\n");} else {printf ("8: not equ\r\n");}*p9= 0x12345678;if (*p9 == 0x12345678) {printf ("9: equ\r\n");} else {printf ("9: not equ\r\n");}*p10= 0x12345678;if (*p10 == 0x12345678) {printf ("10: equ\r\n");} else {printf ("10: not equ\r\n");}}

从最开始宏定义可以知道测试的内存地址,这里把我板子的全部内存做了隔段测试,我的内存地址是从0x30000000到0x4fffffff总共512MB,注意在测试的时候内存地址需要隔4个字节进行测试,也就是最后一位只能取值0、4、8、c这四个值,原因是,我们的内存是32位的也就是4个字节,所以在测试访问的时候需要隔4个字节,注意不能取最后一位除0、4、8、c以外的值,否者就会死掉。

copy_uboot_to_ram()这个拷贝函数的说也参考一个博文http://blog.csdn.net/shangguobuliuhen/article/details/9844371。

同样在main函数中也有LED灯的代码,不过这次换成了C语言的写法,放在这里也是为了判断代码执行的位置,进而判断代码会死在哪里,这个LED定位的思想要灵活运用,可以为你学习和调试带来极大的帮助。就在u-boot中一样我们使用串口打印信息来进行调试一个道理。

第一阶段告一段落,后面继续更新,下一个就是让u-boot能够启动并能进入控制台,过些天在写上来吧。有问题得朋友可以留言,大家共同探讨。

u-boot移植第一弹——制作可用的BL1相关推荐

  1. 【registry】registry合并带spring boot项目第一弹

    1.概述 我现在有一个jetty项目是registry项目是开源的,貌似使用的dropwizard-core框架,现在我有个spring boot项目,想把registry囊括进来,我是直接把regi ...

  2. 【第一弹】经典移植至IOS端、经典合集

    前段时间比较空间,无奈手机又没有一些游戏可玩,之后就在捣鼓一些移植的游戏系列 以免以后在出现手机只能看网页的尴尬局面,也是从网上搜索,整合而至! 一部分是移植到IOS端的,一部分是经典游戏,我也顺道整 ...

  3. 搜狐快站制作html,搜狐快站H5页面设计制作大赛,获奖作品第一弹!

    原标题:搜狐快站H5页面设计制作大赛,获奖作品第一弹! 快海报设计大赛开赛两周以来,已经收到了众多朋友的踊跃投稿.我们从4月15日之前的投稿作品中精选出六部,作为首批获奖者! 我们的比赛并没有结束,下 ...

  4. 与阿里云容器服务 ACK 发行版的深度对话第一弹:如何借助 sealer 实现快速构建 部署

    作者:淮右.王飞.瑜佳 记者: 阿里云原生的读者朋友们大家好,今天应广大感兴趣朋友们的强烈要求,我们邀请来了「阿里云容器服务 ACK 发行版」做客我们的栏目,为大家讲述它的身世之谜,以及它是如何和伙伴 ...

  5. JVM面试八股文第一弹

    大家好,我是路人张,今天更新JVM面试八股文第一弹,JVM这个系列大概会有三到四篇,公众号后台回复"面试手册"可以获取面试后侧PDF版. 推荐阅读: 面试手册第三版,更新! 面试八 ...

  6. 2023春节祝福系列第一弹(下)(放飞祈福孔明灯,祝福大家身体健康)(附完整源代码及资源免费下载)

    2023春节祝福系列第一弹(下) (放飞祈福孔明灯,祝福大家身体健康) (附完整源代码及资源免费下载) 目录 四.画一朵真实的祥云 (1).画一个渐变的白色径向渐变背景 (2).应用一个SVG feT ...

  7. 萝卜魂军曹机器人_《萝卜魂》参战作品详介第一弹:《交响诗篇》

    NBGI近日公布了一款以"Robot魂"可动模型为素材的动作游戏<战斗机器人之魂>,预定于明年春天发售.参战作品有<交响诗篇><剧场版:交响诗篇彩虹满 ...

  8. 2023春节祝福系列第一弹(上)(放飞祈福孔明灯,祝福大家身体健康)(附完整源代码及资源免费下载)

    2023春节祝福系列第一弹(上) (放飞祈福孔明灯,祝福大家身体健康) (附完整源代码及资源免费下载) 目录 一.前言 二.一片星光闪烁的旋转星空 (1).效果展示: (2).相关源代码 (3).语法 ...

  9. 2019奥迪创新实验室大赛招募第一弹|趁现在,定一份未来出行计划

    2019奥迪创新实验室大赛招募第一弹|趁现在,定一份未来出行计划 人们对于出行的想象,从未停止. 1899年,欧洲的一本杂志曾组织一群美术家.插画家,做了关于100年后世界的想象,并把他们想到的样子画 ...

最新文章

  1. 深度学习调参体验(一)
  2. linux进程间通信:popen函数通过管道与shell通信
  3. HTML5 定位 geolocation
  4. 查询一个字符串的子串出现的次数在sql中
  5. 操作系统的安装与启动基本原理
  6. Git学习总结(18)——让你成为Git和GitHub大神的20个技巧
  7. 开箱即用的 Prometheus 告警规则集
  8. Python3的迭代器
  9. 学习java需要用到哪些软件?
  10. 电信版的华为EC6108V9C刷机
  11. rabbitmq消息队列原理
  12. 【Markdown语法】5分钟快速入门保姆级教程(建议收藏...)
  13. php正则替空行,正则匹配空行实例
  14. elementUI动态菜单
  15. 项目实战:51单片机无线音乐门铃设计资料 五首歌曲自由切换 (含实物 图纸 程序 仿真)
  16. java降低if的圈复杂度_几种减少圈复杂度的实践
  17. 微波炉的维修(2)(转自谢工摆渡的博客)
  18. 【使用 arm-poky-linux-gnueabi-gcc -v 指令可以查看 gcc 版本时报错】
  19. 刘汝佳算法竞赛入门例题-循环部分
  20. 基于HTML5的在线地图 - 加载TopoJSON数据

热门文章

  1. latex 波浪线_湖熟镇月牙刀波浪刀带哪家好厂家
  2. oracle产品追溯,如何追溯AR到Receipt再到GL
  3. java学绘图吗_Java绘图
  4. linux哪个命令可以切换工作目录?如何显示当前所在的目录,Linux cd命令:切换目录...
  5. tensorflow gpu python3.5_Win10+Anaconda3下tensorflow-gpu环境配置
  6. 网站使用CloudFlare
  7. 字节月薪6万招 kubernetes 开发,看到要求我傻眼了……
  8. 装X神器!NuShell
  9. 豆瓣读书评分 8.7 以上! 这 40 本 Python 畅销书包邮送
  10. 喜马拉雅 xm文件转m4a_4K YouTube to MP3 Mac(YouTube转mp3软件)