📄 arm芯片s3c2410内存管理单元mmu基础实验 - china linux forum.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0116)http://www.linuxforum.net/forum/showflat.php?Cat=&Board=embedded&Number=586661&page=0&view=collapsed&sb=5&o=0&fpart= -->
<HTML><HEAD><TITLE>ARM芯片S3C2410内存管理单元MMU基础实验 - China Linux Forum</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312"><LINK
href="ARM芯片S3C2410内存管理单元MMU基础实验 - China Linux Forum.files/stylesheet2.css"
type=text/css rel=stylesheet>
<META content="MSHTML 6.00.2900.2769" name=GENERATOR></HEAD>
<BODY><SPAN class=onbody>
<TABLE class=p9 cellSpacing=0 cellPadding=3 width="95%" align=center border=0>
<TBODY>
<TR vAlign=center align=right bgColor=#0099cc>
<TD align=left width="20%"><A
href="http://www.linuxforum.net/index.php"><FONT
color=#ffffff>中国Linux论坛首页</FONT></A></TD>
<TD width="80%"><A
href="http://www.linuxforum.net/forum/ubbthreads.php"><FONT
color=#ffffff>技术论坛|</FONT></A><FON color="#FFFFFF" t> <A
href="http://www.linuxforum.net/docnew/index.php"><FONT
color=#ffffff>文章荟萃</FONT></A><FONT color=#ffffff>| <A
href="http://www.linuxforum.net/books/index.php"><FONT
color=#ffffff>藏经阁</FONT></A>| <A href="http://sf.linuxforum.net/"><FONT
color=#ffffff>项目计划</FONT></A>| <A
href="http://www.linuxforum.net/poll2/index.php"><FONT
color=#ffffff>在线调查</FONT></A>| <A
href="http://www.linuxforum.net/mirror.php"><FONT
color=#ffffff>网站镜像</FONT></A>| <A
href="http://www.linuxforum.net/mirror.php"><FONT
color=#ffffff>软件仓库</FONT></A>| <A
href="http://www.linuxforum.net/about.php"><FONT
color=#ffffff>关于本站</FONT></A>| </FONT></TD></TR></TBODY></TABLE><BR></SPAN>
<TABLE cellSpacing=0 cellPadding=0 width="95%" align=center border=0>
<TBODY>
<TR>
<TD class=tableborders>
<TABLE cellSpacing=1 cellPadding=3 width="100%" border=0>
<TBODY>
<TR>
<TD class=menubar align=right><A
href="http://www.linuxforum.net/forum/ubbthreads.php?Cat=">讨论区列表</A>
| <A href="http://www.linuxforum.net/forum/search.php?Cat=">搜寻文章</A>
| <A
href="http://www.linuxforum.net/forum/newuser.php?Cat=">新用户注册</A> |
<A href="http://www.linuxforum.net/forum/login.php?Cat=">登入论坛</A> |
<A href="http://www.linuxforum.net/forum/online.php?Cat=">在线用户</A> |
<A
href="http://www.linuxforum.net/forum/faq_chinese.php?Cat=">常见问题</A>
</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<P>
<TABLE cellSpacing=0 cellPadding=0 width="95%" align=center border=0>
<TBODY>
<TR>
<TD class=tableborders>
<TABLE cellSpacing=1 cellPadding=3 width="100%" border=0>
<TBODY>
<TR class=darktable>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width="100%">
<TBODY>
<TR class=darktable>
<TD align=left width="33%"><SPAN class=catandforum><A
href="http://www.linuxforum.net/forum/ubbthreads.php?Cat=&C=4">Linux
高级应用</A> <BR> >> <A
href="http://www.linuxforum.net/forum/postlist.php?Cat=&Board=embedded&page=0&view=collapsed&sb=5&o=0">Linux
嵌入技术</A> </SPAN></TD>
<TD align=middle width="33%">此话题阅读次数: 98 </TD>
<TD align=right width="33%">
<TABLE border=0>
<TBODY>
<TR>
<TD class=navigation noWrap><IMG alt=*
src="ARM芯片S3C2410内存管理单元MMU基础实验 - China Linux Forum.files/greyflat.gif"
align=absMiddle>平坦模式 </TD>
<TD class=navigation noWrap><A
href="http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=embedded&Number=586661&page=0&view=collapsed&sb=5&o=0&vc=1"><IMG
alt=树状模式,一封一封读
src="ARM芯片S3C2410内存管理单元MMU基础实验 - China Linux Forum.files/threaded.gif"
align=absMiddle border=0>树状模式</A>
</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=4 width="95%" align=center border=0>
<TBODY>
<TR>
<TD class=small align=left> </TD>
<TD class=small align=right><A
href="http://www.linuxforum.net/forum/printthread.php?Cat=&Board=embedded&main=586661&type=thread"
target=_blank><IMG
src="ARM芯片S3C2410内存管理单元MMU基础实验 - China Linux Forum.files/printthread.gif"
align=top border=0> 打印</A> </TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="95%" align=center border=0>
<TBODY>
<TR>
<TD class=tableborders>
<TABLE cellSpacing=1 cellPadding=3 width="100%" border=0>
<TBODY>
<TR>
<TD class=darktable vAlign=top width="17%" rowSpan=2><A
name=Post586661></A><A
href="http://www.linuxforum.net/forum/showprofile.php?Cat=&User=thisway_diy&Number=586661&Board=embedded&what=showflat&page=0&view=collapsed&sb=5&o=0&fpart=1&vc=1">thisway_diy</A><BR><SPAN
class=small>(stranger)<BR>05-11-12 23:09<BR><A
href="http://www.linuxforum.net/forum/files/586661-MMU.rar">附加档案</A><BR></SPAN></TD>
<TD class=subjecttable width="83%">
<TABLE class=subjecttable width="100%" border=0>
<TBODY>
<TR>
<TD align=left width="70%"><IMG height=15
src="ARM芯片S3C2410内存管理单元MMU基础实验 - China Linux Forum.files/book.gif"
width=15> <B>ARM芯片S3C2410内存管理单元MMU基础实验</B> </TD>
<TD align=right width="30%"> </TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD class=lighttable width="83%"><BR>
<P class=post>前几天看有人需要学习使用MMU,现在把我写的一些东西贴出来。
<BR>附件里是源代码,在这里无法贴图,原文请看: <BR><A
href="http://www.18jin.cn/ShowPost.asp?id=4106"
target=_blank>http://www.18jin.cn/ShowPost.asp?id=4106</A>
<BR><BR>(11)实验十一:MMU
<BR>在理论上概括或解释MMU,这不是我能胜任的。我仅基于为了理解本实验中操作MMU的代码而对MMU做些说明,现在先简单地描述虚拟地址(VA)、变换后的虚拟地址(MVA)、物理地址(PA)之间的关系:
<BR>启动MMU后,S3C2410的CPU核看到的、用到的只是虚拟地址VA,至于VA如何最终落实到物理地址PA上,CPU是不理会的。而caches和MMU也是看不见VA的,它们利用VA变换得来的MVA去进行后续操作——转换成PA去读/写实际内存芯片,MVA是除CPU外的其他部分看见的虚拟地址。对于VA与MVA之间的变换关系,请打开数据手册551页,我摘取了“Figure
2-8. Address Mapping Using CP15 Register 13”: <BR><BR>图4 VA与MVA的关系
<BR>如果VA<32M,需要使用进程标识号PID(通过读CP15的C13获得)来转换为MVA。VA与MVA的转换方法如下(这是硬件自动完成的):
<BR>if(VA < 32M) then <BR>MVA = VA | (PID << 25) //VA <
32M <BR>else <BR>MVA = VA //VA >= 32M
<BR><BR>利用PID生成MVA的目的是为了减少切换进程时的代价:如果两个进程占用的虚拟地址空间(VA)有重叠,不进行上述处理的话,当进行进程切换时必须进行虚拟地址到物理地址的重新影射,这需要重建页表、使无效caches和TLBS等等,代价非常大。但是如果像上述那样处理的话,进程切换就省事多了:假设两个进程1、2运行时的VA都是0-32M,则它们的MVA分别是(0x02000000-0x03ffffff)、(0x04000000-0x05ffffff)——前面说过MMU、Caches使用MVA而不使用VA,这样就不必进行重建页表等工作了。
<BR><BR><BR>现在来讲讲MVA到PA的变换过程:请打开数据手册557页,“Figure 3-1. Translating
Page Tables”(见下述图5)非常精练地概括了对于不同类型的页表,MVA是如何转换为PA的。图中的页表“Translation
table”起始地址为“TTB base”,在建立页表后,写入CP15的寄存器C2。
<BR>使用MVA[31:20]检索页表“Translation
table”得到一个页表项(entry,4字节),根据此entry的低2位,可分为以下4种: <BR>1、0b00:无效
<BR>2、0b01:粗表(Coarse page) <BR>entry[31:10]为粗表基址(Coarse page table
base address),据此可以确定一块1K大小的内存——称为粗页表(Coarse page table,见图5)。
<BR>粗页表含256个页表项,每个页表项对应一块4K大小的内存,每个页表项又可以分为大页描述符、小页描述符。MVA[19:12]用来确定页表项。一个大页(64K)对应16个大页描述符,这16个大页描述符相邻且完全相同,entry[31:16]为大页基址(Large
page
base)。MVA[15:0]是大页内的偏移地址。一个小页(4K)对应1个小页描述符,entry[31:12]为小页基址(Small
page base)。MVA[11:0]是小页内的偏移地址。 <BR>3、0b10:段(Section)
<BR>段的操作最为简单,entry[31:20]为段基址(Section
base),据此可以确定一块1M大小的内存(Section,见图5),而MVA[19:0]则是块内偏移地址
<BR>4、0b11:细表(Fine page) <BR>entry[31:12]为细表基址(Fine page table base
address),据此可以确定一块4K大小的内存——称为细页表(Fine page table,见图5)。
<BR>细页表含1024个页表项,每个页表项对应一块1K大小的内存,每个页表项又可以分为大页描述符、小页描述符、极小页描述符。MVA[19:10]用来确定页表项。一个大页(64K)对应64个大页描述符,这64个大页描述符相邻且完全相同,entry[31:16]为大页基址(Large
page
base)。MVA[15:0]是大页内的偏移地址。一个小页(4K)对应4个小页描述符,entry[31:12]为小页基址(Small
page
base)。MVA[11:0]是小页内的偏移地址。极小页(1K)对应1个极小页描述符,entry[31:10]为极小页基址(Tiny
page base)。MVA[9:0]是极小页内的偏移地址。 <BR><BR>图5 Translating Page Tables
<BR><BR>访问权限的检查是MMU主要功能之一,它由描述符的AP和domain、CP15寄存器C1的R/S/A位、CP15寄存器C3(域访问控制)等联合作用。本实验不使用权限检查(令C3为全1)。
<BR>下面简单介绍一下使用Cache和Write buffer: <BR>1、“清空”(clean)的意思是把Cache或Write
buffer中已经脏的(修改过,但未写入主存)数据写入主存
<BR>2、“使无效”(invalidate):使之不能再使用,并不将脏的数据写入主存
<BR>3、对于I/O影射的地址空间,不使用Cache和Write buffer
<BR>4、在使用MMU前,使无效Cache和drain write buffer
<BR>与cache类似,在使用MMU前,使无效TLB。
<BR>上面有些部分讲得很简略,除了作者水平不足之外,还在于本书的侧重点——实验。理论部分就麻烦各位自己想办法了。不过这些内容也足以了解本实验的代码了。本实验与实验9完成同样的功能:使用按键K1-K4作为4个外部中断——EINT1-3、EINT7,当Kn按下时,通过串口输出“EINTn,Kn
pressed!”,主程序让4个LED轮流从0到15计数。代码在目录MMU下。下面摘取与MMU相关的代码详细说明。
<BR>先看看head.s代码(将一些注释去掉了): <BR>1 b Reset <BR>2 HandleUndef: <BR>3 b
HandleUndef <BR>4 HandleSWI: <BR>5 b HandleSWI <BR>6
HandlePrefetchAbort: <BR>7 b HandlePrefetchAbort <BR>8
HandleDataAbort: <BR>9 b HandleDataAbort <BR>10 HandleNotUsed:
<BR>11 b HandleNotUsed <BR>12 ldr pc, HandleIRQAddr <BR>13
HandleFIQ: <BR>14 b HandleFIQ <BR><BR>15 HandleIRQAddr: <BR>16 .long
HandleIRQ <BR><BR>17 Reset: @函数disable_watch_dog, memsetup,
init_nand, <BR>@nand_read_ll在init.c中定义 <BR>18 ldr sp, =4096 @设置堆栈
<BR>19 bl disable_watch_dog @关WATCH DOG <BR>20 bl memsetup_2
@初始化SDRAM <BR>21 bl init_nand @初始化NAND Flash <BR><BR>22 bl
copy_vectors_from_nand_to_sdram @在init.c中 <BR>23 bl
copy_process_from_nand_to_sdram @在init.c中 <BR><BR>24 ldr sp,
=0x30100000 @重新设置堆栈 <BR>@(因为下面就要跳到SDRAM中执行了) <BR>25 ldr pc,
=run_on_sdram @跳到SDRAM中 <BR>26 run_on_sdram: <BR>27 bl mmu_tlb_init
@调用C函数mmu_tlb_init(mmu.c中),建立页表 <BR>28 bl mmu_init
@调用C函数mmu_init(mmu.c中),使能MMU <BR><BR>29 msr cpsr_c, #0xd2 @进入中断模式
<BR>30 ldr sp, =0x33000000 @设置中断模式堆栈 <BR>31 msr cpsr_c, #0xdf
@进入系统模式 <BR>32 ldr sp, =0x30100000 @设置系统模式堆栈 <BR><BR>33 bl init_irq
@调用中断初始化函数,在init.c中 <BR>34 msr cpsr_c, #0x5f @设置I-bit=0,开IRQ中断
<BR><BR>35 ldr lr, =halt_loop @设置返回地址 <BR>36 ldr pc, =main
@b指令和bl指令只能前后跳转32M的范围, <BR>@所以这里使用向pc赋值的方法进行跳转 <BR>37 halt_loop:
<BR>38 b halt_loop <BR><BR>39 HandleIRQ: <BR>40 sub lr, lr, #4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -