三星S5-PV210内存初始化
一、S5PV210时钟系统
时钟:一定频率的电信号。 时钟系统:基于CMOS工艺的高性能处理器时钟系统,集成PLL可以从内部触发,比从外部触发更快且更准确,能有效地避免一些与信号完整性相关的问题。
S5pv210时钟系统,参考s5pv210手册第三章,CLOCK CONTROLLER
S5pv210时钟管理单元(CMU)主要了解了以下信息
1、时钟域:s5pv210主要由三个时钟域组成
a:MSYS域:Cortex A8处理器、DRAM内存控制器(DMC0和DMC1)、3D、内部SRAM(IRAM和IROM)、INTC和配置接口(SPERI)。Cortex A8仅支持同步模式,因此必须与200MHz轴总线同步运行。
b:DSYS域:与显示相关的模块,包括FIMC、FIMD、JPEG和多媒体IP(X、L和T块中提到的所有其他IP)。都是和视频显示、编解码等有关的模块
c:PSY域:安全、I/O外围设备和低功耗音频播放。如串口、SD接口、I2C、AC97、USB等
每个总线系统分别以200兆赫(最大)、166兆赫和133兆赫运行。在两个不同的域之间有异步总线桥(BRG)。
S5Pv210由三个时钟域组成,即主系统(MSY)、显示系统(DSY)和外围系统(PSY)
2、时钟的声明
S5pv210的时钟包括两种:来自clock pads的时钟,来自CMU的时钟,跟来自USB PHY的时钟
a:来自CLOCK PADS的时钟包括几个晶振接口
•xrtcxti:使用xrtcxti和xrtcxto管脚指定32.768 kHz晶体板的时钟
•xxti:指定从带xxti和xxto针的水晶板的时钟
•xusbxti:指定带有xusbxti和xusbxto引脚的水晶板上的时钟
•xhdmixti:使用xhdmixti和xhdmixto管脚指定27MHz晶体板的时钟
b:来自时钟管理系统(CMU)的时钟
主要分为不同频段的控制输入,在典型的S5Pv210应用中,•Cortex A8和MSys时钟域使用APLL(即,ARMCLK、HCLK-MSY和PCLK-MSY)。
3、时钟的关系
三个时钟域(MSYS时钟域、DSY时钟域、PSY时钟域)对应都有不同对应的取值范围,每个高性能操作的值都对应不同的频率
4、时钟的生成
s5pv210时钟生成的逻辑框图如下
时钟生成器块还包括内置逻辑,用于在每次系统重置后稳定时钟频率,因为时钟在稳定之前需要时间。
s5pv210的两种类型MUX时钟开关:灰色时钟mux表示无故障时钟mux,如果更改时钟选择,则无故障时钟mux。白色的时钟mux代表非无故障时钟mux,在改变时钟源时可能会出现故障。
对于无故障多路复用器,应确保当时钟选择从一个更改为另一个时,两个时钟源都在运行。如果没有同时使用,对于非无故障时钟MUX,在更改时钟时可能会出现故障。时钟更改完成后,用户可以重新启用非无故障时钟MUX的输出,这样就不会因时钟更改而出现故障。非无故障多路复用器的屏蔽输出由时钟源控制寄存器处理。(下面还有时钟源控制寄存器的一些了解)
5、时钟配置程序
基本SFR配置流程:
打开PLL(A、M、E、V)PLL U CON[31]=1;//打开PLL(参考(A、M、E、V)PLL U CON SFR)
wait_lock_time;//等待PLL锁定
(a,m,e,v)pll_sel=1;//在pll输出时钟稳定后,选择pll输出时钟而不是输入参考时钟。
更改系统时钟分频器值clk_div0[31:0]=目标值0;
更改特殊时钟的除法器值clk_div1[31:0]=目标值1;
clk_div2[31:0]=目标值2;
6、S5PV210时钟设置寄存器
-xPLL_LOCK:控制PLL锁定频率的周期,譬如24MHZ变为1GHZ这段是需要一段时间的,通过一个锁相环使得把24MHZ锁定为1GHZ,所以就需要锁定频率的周期了。(锁定频率)
-xPLL_CON:打开/关闭PLL电路,设置PLL的倍频参数,查看PLL锁定状态等。(决定倍频到多少)
-CLK_SRCn(n:0~6):用来设置时钟来源的,对应时钟框图中的mux开关。(决定时钟来源)
-CLK_SRC_MASKn:打开关闭时钟源。(开头部分)
-CLK_DIV_STATn:各模块的分频参数配制。(决定分频多少)
-CLK_SRC_GATE_x:打开关闭时钟门。(结尾部分)
-CLK_DIV_STATn:分频状态寄存器,确保是否已经分频完成。
-CLK_MUX_STATn:选择开关状态寄存器,确保是否已经选择开关完毕。
7、时钟源控制寄存器
S5Pv210有许多时钟源,包括四个PLL输出、外部振荡器、外部时钟和来自GPIO的其他时钟源。CLK U SRCN寄存器控制每个时钟分频器的源时钟。
以此来设置时钟开关
时钟源寄存器(CLK U SRC0,R/W,地址=0XE010 U 0200)
在s5pv210手册中可以看到,所有的寄存器都是按块分的。我们可以找到一个寄存器的基地址,再通过基址加编址寻址的方式在找到寄存器。
8、后面还有s5pv210时钟的MUX状态SFR 以及各种时钟源开关太多了还没看完
二、s5pv210的内存初始化
1、SDRAM定义和特性
SDRAM:Syncronized Dynamic Ramdam Access Memory,同步动态随机存储器
DDR:DDR就是DDR SDRAM,是SDRAM的升级版。(DDR:double rate,双倍速度的SDRAM)
DDR有好多代:DDR1 DDR2 DDR3 DDR4 LPDDR
SDRAM的特性:容量大、价格低、掉电易失性、随机读写、总线式访问。
SDRAM在整个硬件系统中是属于外部设备,通过地址总线和数据总线接口与SoC通信
2、内存地址详解
3:寻址详解
在数据手册《NT5TU64M16GG-DDR2-1G-G-R18-Consumer》第10页的block diagram中,详解如上。
采用128Mb * 8 结构,每个Bank可寻址的大小是16MB,BA0-BA2用来选择8个Bank,寻址的方式:Row-Address+Column-Address。
故单内存芯片可寻址的大小为:16MB * 8 = 128MB
两片单芯片内存并联组合成32位数据总线,可与SoC进行总线通信,可寻址的内存大小便为:128MB+128MB= 256MB,在九鼎的开发板上采用了DRAM0+DRAM1分配内存地址,所以DRAM0和DRAM1都是256MB内存大小,合起来就是512MB内存大小。
所以开发板上DRAM0和DRAM1可寻址的有效范围分别为:
DRAM0:0x20000000 - 0x2FFFFFFF (256MB)
DRAM1:0x40000000 - 0x4FFFFFFF (256MB)
其他地址为非法地址,比如:0x30000000
4、SDRAM初始化详解
初始化过程包括phy dll初始化、设置控制器寄存器和内存初始化。内存初始化请参考JEDEC规范和内存设备数据表。有三种不同的内存类型,即lpddr、lpddr2和ddr2。根据内存类型,初始化顺序如下
1)、Lpddr内存初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言和保持CKE到逻辑的高水平。然后应用稳定时钟。注:xddr2sel应为低电平,以将CKE保持在高电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确的值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部内存芯片,也可以设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,不应为可靠运行而关闭。如果频率低,phy dll可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on bit-字段以关闭phy dll。
13、确认
14、通电后稳定时钟是否至少发出200us。使用directCmd寄存器发出pall命令。
15、使用directCmd寄存器发出两个自动刷新命令。
16、使用directcmd寄存器发出mrs命令以编程操作参数。1-3 S5Pv210_M 1 DRAM控制器
17、使用directcmd寄存器发出emrs命令以编程操作参数。
18、如果有两个外部存储芯片,则对Chip1存储设备执行步骤14~17。
19、将控制器设置为打开自动刷新计数器。
20、如果需要断电模式,请设置MEMControl寄存器。
2)lpddr2内存类型的初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言并将CKE保持在逻辑低水平。然后应用稳定时钟。注:xddr2sel应为高电平,以将CKE保持在低电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部存储器芯片,则设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,phy dll不应关闭以实现可靠的操作。除低频运行外,它可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on位字段以关闭phy dll。
13、将phycontrol1.fp_resync位字段设置为“1”以更新dll信息。
14、确认在通电后,CKE仍保持逻辑低电平至少100ns。
15、发出一个nop命令,使用directcmd寄存器断言和保持CKE到一个逻辑高级。
16、至少等待200us。 1-4 S5Pv210_M 1 DRAM控制器
17、使用directCmd寄存器发出mrs命令以重置内存设备并编程操作参数。
18、等待至少1us。
19、使用directcmd寄存器发出mrr命令来轮询mrstatus寄存器的dai位,以了解设备自动初始化是否完成。
20、如果有两个外部存储芯片,则对chip1存储设备执行步骤15~19。
21、将控制器设置为打开自动刷新计数器。22。如果需要断电模式,设置MEMControl寄存器。
3)DDR2内存类型的初始化顺序:
1. DMC及DDR2颗粒上电, 且电压稳定
2. DMC保持CKE为低电平
3. SOC提供时钟(XDDR2SEL保持高电平以保持CKE为低)
4. 根据实际工作时钟频率设置phyControl0.ctrl_start_point和PhyControl0.ctrl_inc
ldr r0, =APB_DMC_0_BASE @ 0xF000_0000
ldr r1, =0x00101000 @ ctrl_start_point: bit[15:8], ctrl_inc: bit[23:16], 按手册建议,这两位都设置为0x10
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
5. 设置PhyControl0.ctrl_dll_on为”1”, 以使能PHY DLL
ldr r1, =0x00101002 @ctrl_dll_on: bit[1]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
6. DQS Cleaning: 根据实际工作时钟频率和tAC设置PhyControl1.ctrl_shiftc和PhyControl1.ctrl_offsetc (可以和第7步互换顺序)
ldr r1, =0x00000086 @ ctrl_shiftc: bit[2:0], 手册建议设置为6 (DDR2); ctrl_offsetc: bit[14:8], 这里设置为”0”, ctrl_ref: bit[7:4], 默认值为0x4; 所以, 这里应该设置为0x00000046系统也能工作, 设置为”86”可能是原代码作者的错误
str r1, [r0, #DMC_PHYCONTROL1] @ 0xF000_001C
7. 置位PhyControl0.ctrl_start以启动DLL
ldr r1, =0x00101003 @ ctrl_start: bit[0]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
8. 设置ConControl, 注意此时需要保证auto refresh counter off
ldr r1, =0x0FFF2010 @ default time out cycles: FFF; Read data fetch cycles: 2 (CL后再过2个周期latch数据), disable adaptive QoS, disable DQ swap, disable PHY driving (bi-directional pin拉低以省电, enable是不是更好?), disable read cycle gap for 2 different chips (应该是enable),auto refresh counter off, enable out of order scheduling, revise后的设置为(待测试):0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
9. 设置MemControl, 所有power down mode要关掉
ldr r1, =0x00202400 @ MemControl BL=4, 2 chip, 位宽x32 (是指通道位宽), DDR2 type, no additional latency for PALL, disable dynamic self refresh, disable timeout precharge, active/precharge power down, dynamic power down off, dynamic clock control: always running, revise后的设置为(待测试):0x00212400
str r1, [r0, #DMC_MEMCONTROL] @ 0xF000_0004
10. 设置MemControl0和MemControl1寄存器(如果有)
ldr r1, =0x20F01323 @ MemConfig0 设置地址范围0x2000_0000~0x2FFF_FFFF(再在设置的是DMC0,DMC0总共有二片DRAM,每片128MB,因此,严谨的设置应该是0x2000_0000~0x27FF_FFFF, MemConfig1的设置是0x4000_0000~0x47FF_FFFF, 在设置DMC1的流程中,MemConfig0的地址范围可以设置为0x2800_0000~0x2FFF_FFFF, MemConfig1的地址范围设置为0x4800_0000~0x4FFF_FFFF), Mapping Method[15:12] (1:linterleaved), 10bit Column address, 14bit row address, 8 bank, 这样算下来容量不对,查手册得知,应该设置为13bit row address, 8 bank, revised设置:0x20F81313
str r1, [r0, #DMC_MEMCONFIG0] @ 0xF000_0008
ldr r1, =0x40F01323 @ MemConfig1 地址范围0x4000_0000~0x4FFF_FFFF, revised设置:0x40F81313
str r1, [r0, #DMC_MEMCONFIG1] @ 0xF000_000C
补充:
为了DRAM地址的连续性,4片128MB的DDR2可以占用地址空间0x3000_0000~0x4FFF_FFFF,
DMC0_MemConfig0: 0x3000_0000~0x37FF_FFFF
DMC1_MemConfig0: 0x3800_0000~0x3FFF_FFFF
DMC0_MemConfig1: 0x4000_0000~0x47FF_FFFF
DMC1_MemConfig1: 0x4800_0000~0x4FFF_FFFF
11. 设置PrechConfig和PwrdnConfig寄存器
ldr r1, =0xFF000000 @ PrechConfig no precharge for mem0 & mem1
str r1, [r0, #DMC_PRECHCONFIG] @ 0xF000_0014
ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG] @ 0xF000_0028
12. 根据AC parameters时序参数设置TimingAref, TimingRow, TimingData和TimingPower寄存器
ldr r1, =0x00000618 @TimingAref 7.8us*200MHz=1560(0x618)
str r1, [r0, #DMC_TIMINGAREF] @ 0xF000_0030
ldr r1, =0x28233287
@TimingRow @200MHz tRFC[31:24]: 127.5ns/5ns+1, tRRD[23:20]: 7.5ns/5ns+1, tRP[19:16]: 15ns/5ns+1, tRCD[15:12]: 15ns/5ns+1, RC[11:6]: 60ns/5ns+1, tRAS[5:0]: 45ns/5ns+1, revised设置:0x1B34434A
str r1, [r0, #DMC_TIMINGROW] @ 0xF000_0034
ldr r1, =0x23240304
@TimingData @200Mhz tWTR[31:28]: 7.5ns/5ns+1, tWR[27:24]:15ns/5ns+1, tRTP[23:20]: 7.5ns/5ns+1, CL[19:16]=3, reserved[15:12], WL[11:8]: RL-1=3, reserved[7:4], RL[3:0]: 4 by default, AL=4-CL=1, revised设置:0x34330304
str r1, [r0, #DMC_TIMINGDATA] @ 0xF000_0038
ldr r1, =0x09C80232
@TimingPower reserved[31:30], tFAW[29:24]: 37.5ns/5ns+1, tXSR[23:16]: 200clk, tXP[15:8]: 2clk, tCKE[7:4]: 3clk, tMRD[3:0]: 2clk
str r1, [r0, #DMC_TIMINGPOWER] @ 0xF000_003C
13. 如果需要QoS,设置QosControl0~15和QosConfig0~15寄存器
14. 等待PhyStatus0.ctrl_locked置”1”(PHY DLL locked)
find_lock_val:
ldr r1, [r0, #DMC_PHYSTATUS] @ 0xF000_0040 Load Phystatus
and r2, r1, #0x7
cmp r2, #0x7 @Loop until DLL is locked
bne find_lock_val
15. PHY DLL用于制程,电压,温度补偿,DLL开启更可靠,但如果频率很低DLL off也可以正常工作,可以关闭,基于PhyStatus0.ctrl_lock_value[9:2]设置PhyControl0.ctrl_force (BIT[31:24]), 清除PhyControl0.ctrl_dll_on (BIT[1])
and r1, #0x3fc0
@ ctrl_lock_value: bit[13:4], [9:2]相当于ignore最后2bit, 即[13:6]
mov r2, r1, LSL #18
@ LSL: 左移,相当于把ctrl_lock_value这8bit的值赋值到r2的bit[31:24] (DLL Force Delay),
orr r2, r2, #0x100000 @ set bit20, PhyControl0.ctrl_inc=0x10
orr r2 ,r2, #0x1000 @ set bit12, PhyControl0.start_point=0x10
orr r1, r2, #0x3 @ set bit0&1 PhyControl0.ctrl_dll_on&ctrl_start
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
orr r1, r2, #0x1 @ set bit 0 DLL off
str r1, [r0, #DMC_PHYCONTROL0]
16. 确认上电后时钟已经稳定200us
17. 通过DirectCmd寄存器发NOP命令,拉高CKE (DirectCmd见手册1.4.1.5)
ldr r1, =0x07000000 @ DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD] @ 0xF000_0010
18. 等待最小400ns
19. 通过DirectCmd寄存器发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
20. 发EMRS2命令写入工作参数
ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
21. 发EMRS3命令写入工作参数
ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
22. 发EMRS命令使能memory DLL
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
23. 发MRS命令reset memory DLL
ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
24. 发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
25. 发二次Auto Refresh命令
ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]
26. 发MRS命令写入工作参数而不reset memory DLL
ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
27. 等待最少200个时钟周期
28. 发EMRS命令写入工作参数,如果没有使用OCD校准,发EMRS命令设定OCD Calibration Default
ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]
29. 发EMRS命令退出OCD校准模式并写入工作参数
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]
30. 如果有两片DDR2,重新做第17步到29步
ldr r1, =0x07100000 @DirectCmd chip1 Deselect
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00120000 @DirectCmd chip1 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00130000 @DirectCmd chip1 EMRS3
str 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=4
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str 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)
31. 设置ConControl开启auto refresh counter (BIT5)
ldr r1, =0x0FF02030 @ConControl auto refresh on, revised: 0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
32. 如果需要使用power down模式,设置MemControl寄存器
ldr r1, =0x00212400
@MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]
一、S5PV210时钟系统
时钟:一定频率的电信号。 时钟系统:基于CMOS工艺的高性能处理器时钟系统,集成PLL可以从内部触发,比从外部触发更快且更准确,能有效地避免一些与信号完整性相关的问题。
S5pv210时钟系统,参考s5pv210手册第三章,CLOCK CONTROLLER
S5pv210时钟管理单元(CMU)主要了解了以下信息
1、时钟域:s5pv210主要由三个时钟域组成
a:MSYS域:Cortex A8处理器、DRAM内存控制器(DMC0和DMC1)、3D、内部SRAM(IRAM和IROM)、INTC和配置接口(SPERI)。Cortex A8仅支持同步模式,因此必须与200MHz轴总线同步运行。
b:DSYS域:与显示相关的模块,包括FIMC、FIMD、JPEG和多媒体IP(X、L和T块中提到的所有其他IP)。都是和视频显示、编解码等有关的模块
c:PSY域:安全、I/O外围设备和低功耗音频播放。如串口、SD接口、I2C、AC97、USB等
每个总线系统分别以200兆赫(最大)、166兆赫和133兆赫运行。在两个不同的域之间有异步总线桥(BRG)。
S5Pv210由三个时钟域组成,即主系统(MSY)、显示系统(DSY)和外围系统(PSY)
2、时钟的声明
S5pv210的时钟包括两种:来自clock pads的时钟,来自CMU的时钟,跟来自USB PHY的时钟
a:来自CLOCK PADS的时钟包括几个晶振接口
•xrtcxti:使用xrtcxti和xrtcxto管脚指定32.768 kHz晶体板的时钟
•xxti:指定从带xxti和xxto针的水晶板的时钟
•xusbxti:指定带有xusbxti和xusbxto引脚的水晶板上的时钟
•xhdmixti:使用xhdmixti和xhdmixto管脚指定27MHz晶体板的时钟
b:来自时钟管理系统(CMU)的时钟
主要分为不同频段的控制输入,在典型的S5Pv210应用中,•Cortex A8和MSys时钟域使用APLL(即,ARMCLK、HCLK-MSY和PCLK-MSY)。
3、时钟的关系
三个时钟域(MSYS时钟域、DSY时钟域、PSY时钟域)对应都有不同对应的取值范围,每个高性能操作的值都对应不同的频率
4、时钟的生成
s5pv210时钟生成的逻辑框图如下
时钟生成器块还包括内置逻辑,用于在每次系统重置后稳定时钟频率,因为时钟在稳定之前需要时间。
s5pv210的两种类型MUX时钟开关:灰色时钟mux表示无故障时钟mux,如果更改时钟选择,则无故障时钟mux。白色的时钟mux代表非无故障时钟mux,在改变时钟源时可能会出现故障。
对于无故障多路复用器,应确保当时钟选择从一个更改为另一个时,两个时钟源都在运行。如果没有同时使用,对于非无故障时钟MUX,在更改时钟时可能会出现故障。时钟更改完成后,用户可以重新启用非无故障时钟MUX的输出,这样就不会因时钟更改而出现故障。非无故障多路复用器的屏蔽输出由时钟源控制寄存器处理。(下面还有时钟源控制寄存器的一些了解)
5、时钟配置程序
基本SFR配置流程:
打开PLL(A、M、E、V)PLL U CON[31]=1;//打开PLL(参考(A、M、E、V)PLL U CON SFR)
wait_lock_time;//等待PLL锁定
(a,m,e,v)pll_sel=1;//在pll输出时钟稳定后,选择pll输出时钟而不是输入参考时钟。
更改系统时钟分频器值clk_div0[31:0]=目标值0;
更改特殊时钟的除法器值clk_div1[31:0]=目标值1;
clk_div2[31:0]=目标值2;
6、S5PV210时钟设置寄存器
-xPLL_LOCK:控制PLL锁定频率的周期,譬如24MHZ变为1GHZ这段是需要一段时间的,通过一个锁相环使得把24MHZ锁定为1GHZ,所以就需要锁定频率的周期了。(锁定频率)
-xPLL_CON:打开/关闭PLL电路,设置PLL的倍频参数,查看PLL锁定状态等。(决定倍频到多少)
-CLK_SRCn(n:0~6):用来设置时钟来源的,对应时钟框图中的mux开关。(决定时钟来源)
-CLK_SRC_MASKn:打开关闭时钟源。(开头部分)
-CLK_DIV_STATn:各模块的分频参数配制。(决定分频多少)
-CLK_SRC_GATE_x:打开关闭时钟门。(结尾部分)
-CLK_DIV_STATn:分频状态寄存器,确保是否已经分频完成。
-CLK_MUX_STATn:选择开关状态寄存器,确保是否已经选择开关完毕。
7、时钟源控制寄存器
S5Pv210有许多时钟源,包括四个PLL输出、外部振荡器、外部时钟和来自GPIO的其他时钟源。CLK U SRCN寄存器控制每个时钟分频器的源时钟。
以此来设置时钟开关
时钟源寄存器(CLK U SRC0,R/W,地址=0XE010 U 0200)
在s5pv210手册中可以看到,所有的寄存器都是按块分的。我们可以找到一个寄存器的基地址,再通过基址加编址寻址的方式在找到寄存器。
8、后面还有s5pv210时钟的MUX状态SFR 以及各种时钟源开关太多了还没看完
二、s5pv210的内存初始化
1、SDRAM定义和特性
SDRAM:Syncronized Dynamic Ramdam Access Memory,同步动态随机存储器
DDR:DDR就是DDR SDRAM,是SDRAM的升级版。(DDR:double rate,双倍速度的SDRAM)
DDR有好多代:DDR1 DDR2 DDR3 DDR4 LPDDR
SDRAM的特性:容量大、价格低、掉电易失性、随机读写、总线式访问。
SDRAM在整个硬件系统中是属于外部设备,通过地址总线和数据总线接口与SoC通信
2、内存地址详解
3:寻址详解
在数据手册《NT5TU64M16GG-DDR2-1G-G-R18-Consumer》第10页的block diagram中,详解如上。
采用128Mb * 8 结构,每个Bank可寻址的大小是16MB,BA0-BA2用来选择8个Bank,寻址的方式:Row-Address+Column-Address。
故单内存芯片可寻址的大小为:16MB * 8 = 128MB
两片单芯片内存并联组合成32位数据总线,可与SoC进行总线通信,可寻址的内存大小便为:128MB+128MB= 256MB,在九鼎的开发板上采用了DRAM0+DRAM1分配内存地址,所以DRAM0和DRAM1都是256MB内存大小,合起来就是512MB内存大小。
所以开发板上DRAM0和DRAM1可寻址的有效范围分别为:
DRAM0:0x20000000 - 0x2FFFFFFF (256MB)
DRAM1:0x40000000 - 0x4FFFFFFF (256MB)
其他地址为非法地址,比如:0x30000000
4、SDRAM初始化详解
初始化过程包括phy dll初始化、设置控制器寄存器和内存初始化。内存初始化请参考JEDEC规范和内存设备数据表。有三种不同的内存类型,即lpddr、lpddr2和ddr2。根据内存类型,初始化顺序如下
1)、Lpddr内存初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言和保持CKE到逻辑的高水平。然后应用稳定时钟。注:xddr2sel应为低电平,以将CKE保持在高电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确的值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部内存芯片,也可以设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,不应为可靠运行而关闭。如果频率低,phy dll可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on bit-字段以关闭phy dll。
13、确认
14、通电后稳定时钟是否至少发出200us。使用directCmd寄存器发出pall命令。
15、使用directCmd寄存器发出两个自动刷新命令。
16、使用directcmd寄存器发出mrs命令以编程操作参数。1-3 S5Pv210_M 1 DRAM控制器
17、使用directcmd寄存器发出emrs命令以编程操作参数。
18、如果有两个外部存储芯片,则对Chip1存储设备执行步骤14~17。
19、将控制器设置为打开自动刷新计数器。
20、如果需要断电模式,请设置MEMControl寄存器。
2)lpddr2内存类型的初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言并将CKE保持在逻辑低水平。然后应用稳定时钟。注:xddr2sel应为高电平,以将CKE保持在低电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部存储器芯片,则设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,phy dll不应关闭以实现可靠的操作。除低频运行外,它可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on位字段以关闭phy dll。
13、将phycontrol1.fp_resync位字段设置为“1”以更新dll信息。
14、确认在通电后,CKE仍保持逻辑低电平至少100ns。
15、发出一个nop命令,使用directcmd寄存器断言和保持CKE到一个逻辑高级。
16、至少等待200us。 1-4 S5Pv210_M 1 DRAM控制器
17、使用directCmd寄存器发出mrs命令以重置内存设备并编程操作参数。
18、等待至少1us。
19、使用directcmd寄存器发出mrr命令来轮询mrstatus寄存器的dai位,以了解设备自动初始化是否完成。
20、如果有两个外部存储芯片,则对chip1存储设备执行步骤15~19。
21、将控制器设置为打开自动刷新计数器。22。如果需要断电模式,设置MEMControl寄存器。
3)DDR2内存类型的初始化顺序:
1. DMC及DDR2颗粒上电, 且电压稳定
2. DMC保持CKE为低电平
3. SOC提供时钟(XDDR2SEL保持高电平以保持CKE为低)
4. 根据实际工作时钟频率设置phyControl0.ctrl_start_point和PhyControl0.ctrl_inc
ldr r0, =APB_DMC_0_BASE @ 0xF000_0000
ldr r1, =0x00101000 @ ctrl_start_point: bit[15:8], ctrl_inc: bit[23:16], 按手册建议,这两位都设置为0x10
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
5. 设置PhyControl0.ctrl_dll_on为”1”, 以使能PHY DLL
ldr r1, =0x00101002 @ctrl_dll_on: bit[1]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
6. DQS Cleaning: 根据实际工作时钟频率和tAC设置PhyControl1.ctrl_shiftc和PhyControl1.ctrl_offsetc (可以和第7步互换顺序)
ldr r1, =0x00000086 @ ctrl_shiftc: bit[2:0], 手册建议设置为6 (DDR2); ctrl_offsetc: bit[14:8], 这里设置为”0”, ctrl_ref: bit[7:4], 默认值为0x4; 所以, 这里应该设置为0x00000046系统也能工作, 设置为”86”可能是原代码作者的错误
str r1, [r0, #DMC_PHYCONTROL1] @ 0xF000_001C
7. 置位PhyControl0.ctrl_start以启动DLL
ldr r1, =0x00101003 @ ctrl_start: bit[0]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
8. 设置ConControl, 注意此时需要保证auto refresh counter off
ldr r1, =0x0FFF2010 @ default time out cycles: FFF; Read data fetch cycles: 2 (CL后再过2个周期latch数据), disable adaptive QoS, disable DQ swap, disable PHY driving (bi-directional pin拉低以省电, enable是不是更好?), disable read cycle gap for 2 different chips (应该是enable),auto refresh counter off, enable out of order scheduling, revise后的设置为(待测试):0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
9. 设置MemControl, 所有power down mode要关掉
ldr r1, =0x00202400 @ MemControl BL=4, 2 chip, 位宽x32 (是指通道位宽), DDR2 type, no additional latency for PALL, disable dynamic self refresh, disable timeout precharge, active/precharge power down, dynamic power down off, dynamic clock control: always running, revise后的设置为(待测试):0x00212400
str r1, [r0, #DMC_MEMCONTROL] @ 0xF000_0004
10. 设置MemControl0和MemControl1寄存器(如果有)
ldr r1, =0x20F01323 @ MemConfig0 设置地址范围0x2000_0000~0x2FFF_FFFF(再在设置的是DMC0,DMC0总共有二片DRAM,每片128MB,因此,严谨的设置应该是0x2000_0000~0x27FF_FFFF, MemConfig1的设置是0x4000_0000~0x47FF_FFFF, 在设置DMC1的流程中,MemConfig0的地址范围可以设置为0x2800_0000~0x2FFF_FFFF, MemConfig1的地址范围设置为0x4800_0000~0x4FFF_FFFF), Mapping Method[15:12] (1:linterleaved), 10bit Column address, 14bit row address, 8 bank, 这样算下来容量不对,查手册得知,应该设置为13bit row address, 8 bank, revised设置:0x20F81313
str r1, [r0, #DMC_MEMCONFIG0] @ 0xF000_0008
ldr r1, =0x40F01323 @ MemConfig1 地址范围0x4000_0000~0x4FFF_FFFF, revised设置:0x40F81313
str r1, [r0, #DMC_MEMCONFIG1] @ 0xF000_000C
补充:
为了DRAM地址的连续性,4片128MB的DDR2可以占用地址空间0x3000_0000~0x4FFF_FFFF,
DMC0_MemConfig0: 0x3000_0000~0x37FF_FFFF
DMC1_MemConfig0: 0x3800_0000~0x3FFF_FFFF
DMC0_MemConfig1: 0x4000_0000~0x47FF_FFFF
DMC1_MemConfig1: 0x4800_0000~0x4FFF_FFFF
11. 设置PrechConfig和PwrdnConfig寄存器
ldr r1, =0xFF000000 @ PrechConfig no precharge for mem0 & mem1
str r1, [r0, #DMC_PRECHCONFIG] @ 0xF000_0014
ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG] @ 0xF000_0028
12. 根据AC parameters时序参数设置TimingAref, TimingRow, TimingData和TimingPower寄存器
ldr r1, =0x00000618 @TimingAref 7.8us*200MHz=1560(0x618)
str r1, [r0, #DMC_TIMINGAREF] @ 0xF000_0030
ldr r1, =0x28233287
@TimingRow @200MHz tRFC[31:24]: 127.5ns/5ns+1, tRRD[23:20]: 7.5ns/5ns+1, tRP[19:16]: 15ns/5ns+1, tRCD[15:12]: 15ns/5ns+1, RC[11:6]: 60ns/5ns+1, tRAS[5:0]: 45ns/5ns+1, revised设置:0x1B34434A
str r1, [r0, #DMC_TIMINGROW] @ 0xF000_0034
ldr r1, =0x23240304
@TimingData @200Mhz tWTR[31:28]: 7.5ns/5ns+1, tWR[27:24]:15ns/5ns+1, tRTP[23:20]: 7.5ns/5ns+1, CL[19:16]=3, reserved[15:12], WL[11:8]: RL-1=3, reserved[7:4], RL[3:0]: 4 by default, AL=4-CL=1, revised设置:0x34330304
str r1, [r0, #DMC_TIMINGDATA] @ 0xF000_0038
ldr r1, =0x09C80232
@TimingPower reserved[31:30], tFAW[29:24]: 37.5ns/5ns+1, tXSR[23:16]: 200clk, tXP[15:8]: 2clk, tCKE[7:4]: 3clk, tMRD[3:0]: 2clk
str r1, [r0, #DMC_TIMINGPOWER] @ 0xF000_003C
13. 如果需要QoS,设置QosControl0~15和QosConfig0~15寄存器
14. 等待PhyStatus0.ctrl_locked置”1”(PHY DLL locked)
find_lock_val:
ldr r1, [r0, #DMC_PHYSTATUS] @ 0xF000_0040 Load Phystatus
and r2, r1, #0x7
cmp r2, #0x7 @Loop until DLL is locked
bne find_lock_val
15. PHY DLL用于制程,电压,温度补偿,DLL开启更可靠,但如果频率很低DLL off也可以正常工作,可以关闭,基于PhyStatus0.ctrl_lock_value[9:2]设置PhyControl0.ctrl_force (BIT[31:24]), 清除PhyControl0.ctrl_dll_on (BIT[1])
and r1, #0x3fc0
@ ctrl_lock_value: bit[13:4], [9:2]相当于ignore最后2bit, 即[13:6]
mov r2, r1, LSL #18
@ LSL: 左移,相当于把ctrl_lock_value这8bit的值赋值到r2的bit[31:24] (DLL Force Delay),
orr r2, r2, #0x100000 @ set bit20, PhyControl0.ctrl_inc=0x10
orr r2 ,r2, #0x1000 @ set bit12, PhyControl0.start_point=0x10
orr r1, r2, #0x3 @ set bit0&1 PhyControl0.ctrl_dll_on&ctrl_start
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
orr r1, r2, #0x1 @ set bit 0 DLL off
str r1, [r0, #DMC_PHYCONTROL0]
16. 确认上电后时钟已经稳定200us
17. 通过DirectCmd寄存器发NOP命令,拉高CKE (DirectCmd见手册1.4.1.5)
ldr r1, =0x07000000 @ DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD] @ 0xF000_0010
18. 等待最小400ns
19. 通过DirectCmd寄存器发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
20. 发EMRS2命令写入工作参数
ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
21. 发EMRS3命令写入工作参数
ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
22. 发EMRS命令使能memory DLL
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
23. 发MRS命令reset memory DLL
ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
24. 发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
25. 发二次Auto Refresh命令
ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]
26. 发MRS命令写入工作参数而不reset memory DLL
ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
27. 等待最少200个时钟周期
28. 发EMRS命令写入工作参数,如果没有使用OCD校准,发EMRS命令设定OCD Calibration Default
ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]
29. 发EMRS命令退出OCD校准模式并写入工作参数
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]
30. 如果有两片DDR2,重新做第17步到29步
ldr r1, =0x07100000 @DirectCmd chip1 Deselect
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00120000 @DirectCmd chip1 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00130000 @DirectCmd chip1 EMRS3
str 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=4
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str 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)
31. 设置ConControl开启auto refresh counter (BIT5)
ldr r1, =0x0FF02030 @ConControl auto refresh on, revised: 0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
32. 如果需要使用power down模式,设置MemControl寄存器
ldr r1, =0x00212400
@MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]
三星S5-PV210内存初始化的更多相关文章
- Smart210学习记录-------内存初始化
买了Smart210的板子,开始学习中,,,,, 今天看了重定位DRAM ,然而内存需要初始化,早上信心满满的我到现在崩溃的我....也不知遭受了什么样的蹂躏 ,,还是记下一点学到的知识吧.. 数据手 ...
- ok6410内存初始化
•DRAM:它的基本原件是小电容,电容可以在两个极板上保留电荷,但是需要定期的充电(刷新),否则数据会丢失.缺点:由于要定期刷新存储介质,存取速度较慢. •SRAM:它是一种具有静止存取功能的内存,不 ...
- Linux内存初始化
start_kernel -> setup_arch 在这个函数中我们主要看这几个函数. machine_specific_memory_setup max_low_pfn = setup_me ...
- 三星S5驱动安装
三星S5的驱动安装一定要先用原装的数据线链接电脑,在电脑里面安装完驱动之后,以后才能每次都用正常的数据线链接 不然的话会提示某些驱动安装不正常..
- C语言数组内存初始化
内存初始化当然有必然,但是不用memset,直接这样写就可以了:char* szRemoteFile = new char[MAX_LENGTH](); http://blog.csdn.net/pa ...
- X-007 FriendlyARM tiny4412 u-boot移植之内存初始化
<<<<<<<<<<<<<<<<<<<<<<<<< ...
- Linux内存初始化【转】
转自:http://www.cnblogs.com/super-king/p/3291120.html start_kernel -> setup_arch 在这个函数中我们主要看这几个函数. ...
- Linux内存初始化(四) 创建系统内存地址映射
一.前言 经过内存初始化代码分析(一)和内存初始化代码分析(二)的过渡,我们终于来到了内存初始化的核心部分:paging_init.当然本文不能全部解析完该函数(那需要的篇幅太长了),我们只关注创建系 ...
- Linux内存初始化(三) 内存布局
一.前言 同样的,本文是内存初始化文章的一份补充文档,希望能够通过这样的一份文档,细致的展示在初始化阶段,Linux 4.4.6内核如何从device tree中提取信息,完成内存布局的任务.具体的c ...
随机推荐
- windows 删除删除不掉的文件
DEL /F /A /Q \\?\%1RD /S /Q \\?\%1 windows下删除删除不掉的文件: 1.打开记事本,把上面的命令复制进去 2.保存,后缀名改为.bat,ok 3.把想要删除的文 ...
- 实现serializable接口的作用
最重要的两个原因是: 1.将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本: 2.按值将对象从一个应用程序域发送至另一个应用程序域. 实现serializable接口的作用是就是可以 ...
- Oracle 客户端库时引发 BadImageFormatException
程序提示错误: 试加载 Oracle 客户端库时引发 BadImageFormatException.如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题. 出现场 ...
- [翻译] AYVibrantButton
AYVibrantButton https://github.com/a1anyip/AYVibrantButton AYVibrantButton is a stylish button with ...
- 统计过程控制与评价 Cpk、SPC、PPM
Cpk(Process capability index)--工序能力指数 SPC(Statisical Process Control)--工艺过程统计受控状态分析 PPM(Parts Per Mi ...
- September 26th 2017 Week 39th Tuesday
I have to protect the one thing I can't live without. 我必须为我一生挚爱遮风挡雨. A man is a success if he gets u ...
- WCF自寄宿实现Https绑定
一.WCF配置 1 Address 将服务端发布地址和客户端访问地址都配置为https开始的安全地址.参考如下. <add key="SrvUrl" value=" ...
- delete obj$
//////要用system,dba身份登入进去//////select * from obj$ oWHERE o.obj#=149554where o.name='MV_ZD_QLR' delete ...
- Git 如何上传文件夹
Github开源代码库以及版本控制系统,可以托管各种git库,并提供web访问界面.很多朋友喜欢喜欢将个人Blog或小型项目托管到github,这样既方便又简单. 下面介绍如何将本地文件上传到gith ...
- 解决数据库自增ID的问题
(1)设置主键自增为何不可取这样的话,数据库本身是单点,不可拆库,因为id会重复. (2)依赖数据库自增机制达到全局ID唯一使用如下语句:REPLACE INTO Tickets64 (stub) V ...