??xml version="1.0" encoding="utf-8" standalone="yes"?>99久久精品免费观看国产,Xx性欧美肥妇精品久久久久久,午夜福利91久久福利http://www.shnenglu.com/jinglexy/category/4078.html冠盖满京华,斯h独憔_zh-cnTue, 06 Jan 2009 14:53:06 GMTTue, 06 Jan 2009 14:53:06 GMT60发布_版cygwin-2009.isohttp://www.shnenglu.com/jinglexy/archive/2009/01/06/71371.html天衣有缝天衣有缝Tue, 06 Jan 2009 11:46:00 GMThttp://www.shnenglu.com/jinglexy/archive/2009/01/06/71371.htmlhttp://www.shnenglu.com/jinglexy/comments/71371.htmlhttp://www.shnenglu.com/jinglexy/archive/2009/01/06/71371.html#Feedback1http://www.shnenglu.com/jinglexy/comments/commentRss/71371.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/71371.html
(1)cygwin 2009Q集成gcc-4.3.2QrxvtQ非帔R合一般的~程开发,集成iso?8M
(2)i686-elf的cygwin toolchainQ工具链版本Qgcc-4.3.2, binutils-2.19, glibc-2.7Q测试正常工?br>以此工具铄译最新的linux内核2.6.28工作正常Qkernel打一些补丁:
    cd linux-2.6.28
    sed -i 's/R_386_32/1/' ./scripts/mod/modpost.c
    sed -i 's/R_386_PC32/2/' ./scripts/mod/modpost.c
    sed -i 's/R_ARM_ABS32/2/' ./scripts/mod/modpost.c
    sed -i 's/R_ARM_PC24/1/' ./scripts/mod/modpost.c
    sed -i 's/R_MIPS_HI16/5/' ./scripts/mod/modpost.c
    sed -i 's/R_MIPS_LO16/6/' ./scripts/mod/modpost.c
    sed -i 's/R_MIPS_26/4/' ./scripts/mod/modpost.c
    sed -i 's/R_MIPS_32/2/' ./scripts/mod/modpost.c

    sed -i 's/STT_COMMON/5/g' ./arch/x86/boot/compressed/relocs.c

    sed -i 's/STV_DEFAULT/0/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/STV_INTERNAL/1/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/STV_HIDDEN/2/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/STV_PROTECTED/3/g' ./arch/x86/boot/compressed/relocs.c

    sed -i 's/R_386_NONE/0/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_32/1/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_PC32/2/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_GOT32/3/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_PLT32/4/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_COPY/5/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_GLOB_DAT/6/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_JMP_SLOT/7/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_RELATIVE/8/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_GOTOFF/9/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_GOTPC/10/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/R_386_NUM/11/g' ./arch/x86/boot/compressed/relocs.c

    sed -i 's/ELF32_ST_VISIBILITY(sym->st_other)/sym->st_other \& 0x03/g' ./arch/x86/boot/compressed/relocs.c
    sed -i 's/else rm -f $(@D)\/.tmp_$(@F); exit 1;/else mv -f $(@D)\/.tmp_$(@F) $@;/' ./arch/x86/vdso/Makefile

menuconfig中把netfilterLQ里面有一些文件名一P大小写不一PQipv6也去掉,~译的elf文g正常?br>
上v漕河?br>2009.01.06




天衣有缝 2009-01-06 19:46 发表评论
]]>
mm(use slab arithmetic) for jinix-1.2.1Q原创)http://www.shnenglu.com/jinglexy/archive/2007/11/21/37103.html天衣有缝天衣有缝Wed, 21 Nov 2007 12:23:00 GMThttp://www.shnenglu.com/jinglexy/archive/2007/11/21/37103.htmlhttp://www.shnenglu.com/jinglexy/comments/37103.htmlhttp://www.shnenglu.com/jinglexy/archive/2007/11/21/37103.html#Feedback0http://www.shnenglu.com/jinglexy/comments/commentRss/37103.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/37103.html阅读全文

天衣有缝 2007-11-21 20:23 发表评论
]]>
jinix内核虚拟控制台实玎ͼ原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/07/10/27828.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Tue, 10 Jul 2007 12:15:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/07/10/27828.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/27828.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/07/10/27828.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/27828.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/27828.html</trackback:ping><description><![CDATA[     摘要: jinix是小弟正在实现的一个c++ kernelQ因试缘故,所以早早的把控制台部分调出来了Q以便于后来的调试。代码用c++写的Q如果用c写内怹很容易移植过厅R{载请保留?创:http://www.shnenglu.com/jinglexyQmail & msn: jinglexy at yahoo dot com dot cn。这部分代码是在内存理之前实现的,所以没有做CQ...  <a href='http://www.shnenglu.com/jinglexy/archive/2007/07/10/27828.html'>阅读全文</a><img src ="http://www.shnenglu.com/jinglexy/aggbug/27828.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-07-10 20:15 <a href="http://www.shnenglu.com/jinglexy/archive/2007/07/10/27828.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OS调试相关的工P附图Q原创)http://www.shnenglu.com/jinglexy/archive/2007/06/28/27133.html天衣有缝天衣有缝Thu, 28 Jun 2007 03:02:00 GMThttp://www.shnenglu.com/jinglexy/archive/2007/06/28/27133.htmlhttp://www.shnenglu.com/jinglexy/comments/27133.htmlhttp://www.shnenglu.com/jinglexy/archive/2007/06/28/27133.html#Feedback6http://www.shnenglu.com/jinglexy/comments/commentRss/27133.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/27133.html
如果pȝ处于仿真的初期节点,例如操作pȝ的初始化Q调试还是很有必要的。这里是我在linux环境调试操作pȝ的相兛_Pos开发者可参考,Ƣ迎指正Q)
Q?Q工具安装:
linux安装Qbochs-2.3Qinsight-6.6Qgcc-3.4Q用g++和asQbinutils包中Q)
windows安装QXmanager Enterprise2.1
因ؓ|管没有lotus和clearcase在linuxpȝ下的支持Q所以只好用两个操作pȝ了。这样也比较好,一个用于programQ一个用于调试,毕竟bochscpu的,p她干zd了?br>bochs安装Q?/configure --with-all-libs --enable-vbe --enable-gdb-stub && make && make install
insight-6.6安装Q包含了tck/tkQgdb-6.6Qbfd{工P使用insight时最好这栯|环境变量:
export LC_ALL=en_US
否则q行时可能会报错Q?br>Tcl_Init failed: can't read "env(TCL_LIBRARY)": no such variable
配置xserver用于q程讉KLinux囑Ş界面Q这样可以在windows上通过ssh执行linux的图形界面程序?br>

Q?Q相xӞ
bochs配置文gd如下节:
gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0

gdb调试脚本Q?br>gdb的命令集可以写入C个文件中去,q样避免了在启动时输入一大堆命oQ?00%鼠标操作Qfaint
保存所有命令到一个文Ӟ每行一个命令,如下Q?br>file ./vmjinix
target remote 127.0.0.1:1234
dir  ./arch/i386
dir  ./init
dir  ./kernel
dir  ./drivers
dir  ./drivers/video
dir  ./drivers/video/console
show dir
break start_kernel
continue
list 0
gdb和gdb前端执行如下Q?br>gdb -q -x gdb.command
insight -q -x gdb.command

其他脚本Q磁盘自动创建分区,自动安装grubQ拷贝内核,及Makefile脚本Q,q些贴出来太长,׃好几个小时写好的Q需要可以和我联p(MSN & EmailQjinglexy at yahoo dot com dot cnQ?br>
Q?Q调试方?br>内核(jinix-1.2.1是我正在~写的一个C++ 开源OSQ欢q参与)拯到linuxLQ配|samba׃nQ这样可以在windows上开发(推荐使用slickedit 2007Q哪位有linux上的2007版本可否发一个给我)?br>使用xshellQssh方式Q登录到linuxL上,~译和调试都在这里了?br>在ssh上执行bochs -f bochsrc.txt.linuxQ?br>在ssh上执行insight -q -x gdb.command
截图如下Q?br>


汇编语言节点也可用用bochsQgdb调试Q在gdb断点时候执行:
disassemble $pc $pc+100Q从当前断点处反汇编100字节Q?br>需要注意的是,在os的汇~初始化的前期阶D,分页机制往往未开启,W号和地址不能一一对应Q?br>q个时候不能进行源码汇编调试Q只能用最即便的反汇编调试了?br>bochs-2.3中好像有个bug没有解决Qnexti执行和stepi在call的时候居然一P如果要断点到指定行,可以使用物理地址断点?br>
Q?Q文章会不断更新Q如有什么好的想法可以在原博客讨论:
http://www.shnenglu.com/jinglexy

Q?Q整理的一份常用gdb指o
x  /4wx ds:0x1234            x是线性地址I间
xp /4wx 0x1234                xp是物理地址I间
backtrace
print  variable                打印变量?br>print  variable@10            打印变量后面?0个整数?br>set    variable=2            赋?br>whatis variable                昄变量cd
ptype  variable                昄数据l构Q变量类型加强版Q?br>
断点cdQ?br>break init_kernel.cpp:start_kernel    断点在文件的函数
break init_kernel.cpp:101        断点在文件的101?br>break init_kernel.cpp:101 if var==100    条g断点
break *0xc0102030
info break                查看所有断?br>delete breakpoint 3
delete breakpoint            删除所有断?br>isable breakpoint 2
enable breakpoint 2


search string1                搜烦字符Ԍ从listl束行开?br>reverse-search string1            方向搜烦
set history expansion on        使用历史命o
clear                    删除刚才停止处的断点
continue                从断点开始l执?br>info break                昄当前断点清单Q包括到达断点处的次数等
info files                昄被调试文件的详细信息
info func                昄所有的函数名称
info local                昄当函C的局部变量信?br>info prog                昄被调试程序的执行状?br>info var                昄所有的全局和静态变量名U?br>info all
run
continue
step, next, stepi, nexti        i后缀表示执行一条汇~指?br>
/*********************************************************************************
                                      格式说明                                   /
/*********************************************************************************
x  /nuf addr查位于线性地址addr处的内存内容Q若addr不指定,则默认ؓ下一个单元地址?br>xp /nuf addr查位于物理地址addr处的内存内容?br>其中的可选参数n、u和f的分别可为:
nƲ显C内存单元的计数|默认gؓ1?br>u表示单元大小Q默认选择?w'Q?br>b QBytesQ?字节Q?br>h QHalfwordsQ?字节Q?br>w QWordsQ?字节Q?br>g QGiantwordsQ?字节?br>注意Q这些羃略符与Intel的不同,主要是ؓ了与GDB调试器的表示法一致?br>f昄格式Q默认选择?x'Q?br>x QhexQ显CZؓ十六q制敎ͼ默认选择Q;
d QdecimalQ显CZؓ十进制数Q?br>u QunsignedQ显C成无符号十q制敎ͼ
o QoctalQ显C成八进制数Q?br>t QbinaryQ显C成二进制数?br>c QcharQ显C字节代码对应的字符。若不是可显C字W代码,q接显CZ码?br>*********************************************************************************/

说明一下:bochs ?insight本n单个执行非常慢Q而且insight是通过ssh方式链接q程xserver执行Q所以速度巨慢Q本文所q完全可以全部在linux上操作,不限于^台?br>



天衣有缝 2007-06-28 11:02 发表评论
]]>
C++写内栔R要注意的一些事情(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/06/25/26940.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Mon, 25 Jun 2007 13:19:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/06/25/26940.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/26940.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/06/25/26940.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/26940.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/26940.html</trackback:ping><description><![CDATA[内核当然可用用c++来些Q但是相对c来说有许多要注意的地方,我们不得不关掉一些特性。这里只提一些gcc相关的内容,Microsoft VC我没有尝试。{载请注明原创Q天衣有~(http://www.shnenglu.com/jinglexyQ,MSN: jinglexy at yahoo dot com dot cn<br><br>1)g++选项-nostartfilesQ用L境的在main之前调用的代码,当然不能使用?br>2)全局对象Q每U类型都有自q构造函敎ͼ如果不自q写代码调用,它们不会执行?br>q包括所有全局对象和局部static对象Q徏议的做法是在内核栈徏立后Qc++q行代码执行之前<br>调用构造函敎ͼ如果构造函数没有运行(假设里面有分配内存之cȝ操作Q,后果很严重:Q?br>我们可以q样做:<br>先修改gnu-ld链接脚本<br>.data : { <br>    start_ctors = .;<br>    *(.ctor*)<br>    end_ctors = .;<br>    start_dtors = .;<br>    *(.dtor*)<br>    end_dtors = .;<br><br>    *(.data)<br>}<br>q样构造函数的指针都保存在start_ctors 和end_ctors之间的内存中了,构造函数其实就是void foo(void);形式的函敎ͼ~写一个for循环<br><br>调用它即可;析构函数也是一L。当每个构造函数调用完后,gcc会自动调用一个函敎ͼ<br>int __cxa_atexit(void (* f)(void *), void *p, void *d);<br>当内栔R出时Q会执行一个函敎ͼ<br>void __cxa_finalize(void *d);<br>q两个函数必L上面格式定义Qg++是这栯定的。看看下面的代码明白了Q?br>extern "C"<br>        {<br>        int __cxa_atexit(void (*f)(void *), void *p, void *d);<br>        void __cxa_finalize(void *d);<br>        };<br><br>void *__dso_handle; /*only the address of this symbol is taken by gcc*/<br><br>struct object<br>{<br>        void (*f)(void*);<br>        void *p;<br>        void *d;<br>} object[32] = {0};<br>unsigned int iObject = 0;<br><br>int __cxa_atexit(void (*f)(void *), void *p, void *d)<br>{<br>        if (iObject >= 32) return -1;<br>        object[iObject].f = f;<br>        object[iObject].p = p;<br>        object[iObject].d = d;<br>        ++iObject;<br>        return 0;<br>}<br><br>/* This currently destroys all objects */<br>void __cxa_finalize(void *d)<br>{<br>        unsigned int i = iObject;<br>        for (; i > 0; --i)<br>        {<br>                --iObject;<br>                object[iObject].f(object[iObject].p);<br>        }<br>}<br><br>3)new和deleteQ在完成内存理后,重蝲cȝnew和delete函数<br>4)-nostdlibQ把标准库禁用掉Q最q有了移植stl到内核的x<br>5)RTTIQ最好是止它,q样不能用typeid ?dynamic_cast?br>6)用异常Q?fno-exceptionsQ这个和操作pȝ太紧密了<br>7)U虚函数Q如果子cL有实现父cM的纯虚函敎ͼ链接C面默认例E:<br>extern "C" void __cxa_pure_virtual()<br>{<br>    // print error message<br>}<br>虽然不是Z定义U虚cȝ对象Q但是链接时~译器会抱怨,所以定义上面函Cɾ~译通过?br>8)如果一定要使用异常QrttiQnew/deleteQgcc中提供了静态库Qlibgcc/libsupc++Q?br>q得写这个库的一些基函数Q觉得它应该是在上层抽象出接口,底层实现空出来l用户实现?br>而且代码本n非常复杂Q网l上也没有Q何中文资料?br>指oQ?br>readelf -a `gcc -print-libgcc-file-name`<br>里面定义了很多的函数?br><br> <img src ="http://www.shnenglu.com/jinglexy/aggbug/26940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-06-25 21:19 <a href="http://www.shnenglu.com/jinglexy/archive/2007/06/25/26940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(pdfQchmQsource下蝲Q(20070711修订版,原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/06/11/26021.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Mon, 11 Jun 2007 02:00:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/06/11/26021.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/26021.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/06/11/26021.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/26021.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/26021.html</trackback:ping><description><![CDATA[以前一pd的文章整理在下面包中Qchm格式和pdf格式Q及所有源E序Q?br>http://blogimg.chinaunix.net/blog/upfile2/080524213721.rar<br><br> 目录Q?br> 自己动手写内核(序)......................... 3<br> W? 课:环境需?............................ 4<br> W? 课:引导E序............................. 5<br> W? 课:保护模式............................. 8<br> W? 课:辅助函数............................. 17<br> W? 课:中断和异?.......................... 25<br> W? 课:中断和异?.......................... 39<br> W? 课:多Q?.............................. 45<br> W? 课:文gpȝ............................. 56<br> W? 课:内存理............................. 70<br> W? 课:pȝ调用和可执行E序................. 76<br> 一份免责声?................................ 81<br><br><br> <img src ="http://www.shnenglu.com/jinglexy/aggbug/26021.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-06-11 10:00 <a href="http://www.shnenglu.com/jinglexy/archive/2007/06/11/26021.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(W?课:内存理Q(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/06/08/25801.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Fri, 08 Jun 2007 00:44:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/06/08/25801.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/25801.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/06/08/25801.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/25801.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/25801.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">  <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">W?span lang="EN-US">8</span>课:内存理<span lang="EN-US">    <a target="_blank"><span lang="EN-US"><span lang="EN-US">下蝲源代?/span></span></a><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">声明Q{载请保留Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">译者:<span lang="EN-US">http://www.shnenglu.com/jinglexy<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">原作者:<span lang="EN-US">xiaoming.mo at skelix dot org<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">MSN & Email: jinglexy at yahoo dot com dot cn<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: blue;">目标</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">抱歉Q其实还没有实现。在d分配独立?span lang="EN-US">4G</span>地址I间上调试失败了Q现在只使能了分|Ӟ异常。大量的工作未实玎ͼ有兴的同学可以搜烦<span lang="EN-US">buddy</span>?span lang="EN-US">slab</span>的相兌料,l典的内存管理算法?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> </span><span style="font-size: 12pt; font-family: 宋体; color: blue;">分页</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">386</span><span style="font-size: 12pt; font-family: 宋体;">处理器的内存理单元可以实现d独立地址I间QQ务间内存保护。每个Q务可以拥有独立的<span lang="EN-US">4G</span>虚拟地址I间。内存映是内存理很重要的一步,可以分ؓ两部分:分段和分c前面的评中已l讨分段机制了,通过分段可以隔开不同的代码,数据Q堆栈等Q分单元把虚拟地址映射成物理地址Q还可以用来实现虚拟内存Q和盘分区q行交换Q,现在我们来了解一下它?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">对于每个dQ我们无法分?span lang="EN-US">4G</span>的物理内存,所以用了一些机制来理内存Q及虚拟内存机制。该机制有处理器的分部分来实现Q首先我们将内存分成一些块Q每个块大小?span lang="EN-US">4k</span>Q通常我们UCZ个页帧。操作系l通过늛录和表来管理这些页帧。页目录是相当于W一U页表,其中的每一再理一个下U页表。(更详l过E请参?span lang="EN-US">intel</span>?span lang="EN-US">IA 32/64</span>手册Q?span lang="EN-US"><br> <br> </span>当分|制开启时Q处理器把Q务中的虚拟地址转换成物理地址Q步骤如下:<span lang="EN-US"><br> 1.</span>查找D选择子在<span lang="EN-US">GDT </span>?span lang="EN-US"> LDT </span>中的描述W,做一些权限检查,看看能否讉K<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">2.</span><span style="font-size: 12pt; font-family: 宋体;">以描q符中的基址相加늛录基址得到一个线性地址<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">3.</span><span style="font-size: 12pt; font-family: 宋体;">在页表中索引虚拟地址所对应的页表项Q得到页地址<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">4.</span><span style="font-size: 12pt; font-family: 宋体;">查找偏移得到实际物理地址?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">如果实际物理不存在Q可能交换到盘中去了)Q则引发异常Q可以在q个异常里面做想要做的事情(加蝲盘中的交换,或?span lang="EN-US">kill</span>q个E序Q?span lang="EN-US">Segment Fault</span>Q等{)<span lang="EN-US"><br> <br> </span>处理器用的늛录或者页表,都是?span lang="EN-US">32 </span>位的组成:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: blue;">늛录项Q?/span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> 31                    12    11    9    876   5   43    2     1     0<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">?nbsp;  </span><span style="font-size: 12pt; font-family: 宋体;">指向表的物理地址<span lang="EN-US">  ?</span>用户定义<span lang="EN-US"> ?nbsp; X  ?nbsp;A? X ?U/S?R/W?P ?o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: blue;">表:</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> 31                    12    11    9   87  6  5   43    2     1     0<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">?nbsp;  </span><span style="font-size: 12pt; font-family: 宋体;">指向的物理地址<span lang="EN-US">  ?</span>用户定义<span lang="EN-US"> ?nbsp;X┃D?nbsp;A?X ? U/S?R/W?P ?o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">从上面可以知道,늛录项和页表项的结构很cMQ下面逐个说明一下其中的域:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p> </o:p></span></p> <table class="MsoNormalTable" style="width: 79.58%;" border="1" cellpadding="0" width="79%"> <tbody> <tr> <td style="padding: 1.5pt; width: 84.75pt;" valign="top" width="113"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bit  0<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 63pt;" valign="top" width="84"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">P<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 393.75pt;" valign="top" width="525"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">存在位(<span lang="EN-US">present</span>Q,?span lang="EN-US">0 </span>表示该页帧或表不在内存中。如果访问该将发生异常?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 84.75pt;" valign="top" width="113"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bit  1<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 63pt;" valign="top" width="84"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">R/W<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 393.75pt;" valign="top" width="525"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">表示表或页帧指向的内存只读Q=<span lang="EN-US">0</span>Q,或可写(Q?span lang="EN-US">1</span>Q?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 84.75pt;" valign="top" width="113"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bit  2<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 63pt;" valign="top" width="84"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">U/S<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 393.75pt;" valign="top" width="525"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">表示表或页帧的权限Q当ҎUؓ<span lang="EN-US">0</span>Ӟ只有<span lang="EN-US">ring0</span>?span lang="EN-US">2</span>的特权可以讉K它,否则所有的<span lang="EN-US">ring3</span>d都可以访问。这个域非常重要?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 84.75pt;" valign="top" width="113"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bits 3, 4, (6), 7, 8<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 63pt;" valign="top" width="84"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">X<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 393.75pt;" valign="top" width="525"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Intel </span><span style="font-size: 12pt; font-family: 宋体;">保留位,讄?span lang="EN-US">0</span>p?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 84.75pt;" valign="top" width="113"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bit  5<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 63pt;" valign="top" width="84"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">A<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 393.75pt;" valign="top" width="525"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">该页是否已访?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 84.75pt;" valign="top" width="113"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bits 9-11<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 63pt;" valign="top" width="84"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">用户定义<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt; width: 393.75pt;" valign="top" width="525"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们使用W?span lang="EN-US">11</span>位,表示该页帧是否被交互到硬盘上?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> </tbody> </table> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">늛录的每一:即页表的物理地址Q它的高<span lang="EN-US">20 </span>位地址表示有个的v始地址Q正好和<span lang="EN-US">4k</span>寚w?span lang="EN-US">2^20</span>可以表示<span lang="EN-US">1M</span>范围Q每个页帧大是<span lang="EN-US">4k</span>Q所以可以烦?span lang="EN-US">1M * 4K</span>地址I间。页目录中q有一?span lang="EN-US">D </span>位,它用来表CZ个页帧是否已修改Q?span lang="EN-US">linux</span>用它来表CZ个页面释放是脏页面,q个位非常有用,当一个页帧交换到盘上后Q如果该q没有被修改Q而且是已l从盘交换出来的,则简单取消以后的交换?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Z逻辑地址转换成物理地址Q逻辑地址被分?span lang="EN-US">3 </span>部分Q?span lang="EN-US"><o:p></o:p></span></span></p> <table class="MsoNormalTable" style="width: 79.58%;" border="1" cellpadding="0" width="79%"> <tbody> <tr> <td style="padding: 1.5pt; width: 101.25pt;" valign="top" width="135"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bits 31-22<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 437.25pt;" valign="top" width="583"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">늛录项的烦引下标,由它可以得到表的物理地址<span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 101.25pt;" valign="top" width="135"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bits 21-12<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 437.25pt;" valign="top" width="583"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">表的索引下标Q由它可以得到页帧的物理地址<span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 101.25pt;" valign="top" width="135"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bits 11-0<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 437.25pt;" valign="top" width="583"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">相对起始地址的偏U?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> </tbody> </table> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">举例来说Q我们有一个逻辑地址Q?span lang="EN-US">0x3E837B0A</span>。前提条Ӟ<span lang="EN-US">CR3</span>寄存器指向的늛录地址?span lang="EN-US"> 0x0005C000</span>Q这个寄存器存储了当前页目录所使用的页帧的物理地址Q通常也叫?span lang="EN-US"> PDBR</span>?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">先取它的?span lang="EN-US">10</span>位, 是<span lang="EN-US">0x0FA</span>Q由它可以烦引到늛录的W?span lang="EN-US">0x0FA</span>,我们取得q一的|假设得到的地址值是<span lang="EN-US">0x0003F000</span>。然后我们取虚拟地址的中?span lang="EN-US">10</span>位,是<span lang="EN-US">0x037</span>Q再取出<span lang="EN-US">0x0003F000</span>指向的第<span lang="EN-US">0x037</span>的|假设?span lang="EN-US">0x0001B000</span>。这个地址是我们要找的虚拟地址对应的物理地址的页帧的起始地址Q最后加上偏Ud|?span lang="EN-US">12</span>位)Q即<span lang="EN-US">0xB0A</span>Q得到实际的物理地址是:<span lang="EN-US">0x0001BB0A</span>?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">相关的知识可以参?span lang="EN-US"> Intel </span>?span lang="EN-US">IA 32/64</span>手册?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">CR3</span><span style="font-size: 12pt; font-family: 宋体;">寄存器必d分页机制开启前p载好Q可以?span lang="EN-US">MOV </span>指o或者在d切换时?span lang="EN-US">TSS</span>中的<span lang="EN-US">CR3</span>域的倹{当处理器访问不存在的页帧时Q发生一个异常,<span lang="EN-US">CR2 </span>寄存器存引发异常的逻辑地址Q同旉误码也会压入到堆栈中Q错误码格式如下Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> 31                                                 3   2     1     0<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">?nbsp;                   </span><span style="font-size: 12pt; font-family: 宋体;">未?span lang="EN-US">                         ?U/S?R/W?P ?o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">异常处理例程通常采取如下的步骤:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">查找一个空闲的或从盘中将交换出来Q重新设|正的늛录项或页表项的|h<span lang="EN-US">TLB</span>。处理器通常保存最q最多访问的늛录或表到一?span lang="EN-US">cache</span>中,以避免每ơ都q行虚拟地址到物理地址的{换,q个<span lang="EN-US">cache</span>叫?span lang="EN-US">TLB</span>。只有我们改动了늛录或表,应当刷?span lang="EN-US">TLB</span>。方法很单,是重新加蝲<span lang="EN-US">CR3 </span>寄存器?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> </span><span style="font-size: 12pt; font-family: 宋体;">现在我们来看看代码段Q内存管理通常不了大量的宏定义:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: red;" lang="EN-US">08/include/kernel.h</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">#define PAGE_DIR    ((HD0_ADDR+HD0_SIZE+(4*1024)-1) & 0xfffff000)<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">物理内存安排Q?span lang="EN-US">IDT</span>Q在<span lang="EN-US">0x40000</span>Q,接下来是<span lang="EN-US">GDT</span>Q接下来?span lang="EN-US">HD0</span>使用Q然后才是页目录Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">所以这个宏看v来有炚w?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> <span style="color: red;">08/include/mm.h</span><br> #define PAGE_SIZE    (4*1024)                    /* </span><span style="font-size: 12pt; font-family: 宋体;">_度<span lang="EN-US"> */<br> #define PAGE_TABLE    (PAGE_DIR+PAGE_SIZE)       /* </span>表物理地址<span lang="EN-US"> */<br> #define MEMORY_RANGE (4*1024)                    /* skelix</span>只管?span lang="EN-US">4M </span>内存暂时<span lang="EN-US"> */<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> <span style="color: red;">08/mm.c</span><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">/* </span><span style="font-size: 12pt; font-family: 宋体;">物理内存使用情况的位图表<span lang="EN-US"> */<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">static char mmap[MEMORY_RANGE/PAGE_SIZE] = {PG_REVERSED, };<br> <br> void<br> mm_install(void) {<br>     unsigned int *page_dir = ((unsigned int *)PAGE_DIR);<br>     unsigned int *page_table = ((unsigned int *)PAGE_TABLE);<br>     unsigned int address = 0;<br>     int i;<br>     for(i=0; i<MEMORY_RANGE/PAGE_SIZE; ++i) {<br>         /* </span><span style="font-size: 12pt; font-family: 宋体;">表属性设|ؓ<span lang="EN-US">: kernel, r/w, present */<br>         page_table[i] = address|7;<br>         address += PAGE_SIZE;<br>     };<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    // </span><span style="font-size: 12pt; font-family: 宋体;">上面循环初始化了<span lang="EN-US">0~4M</span>对应的所有页表项<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br>     page_dir[0] = (PAGE_TABLE|7);<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    // </span><span style="font-size: 12pt; font-family: 宋体;">늛录项只需要第一个就可以了,因ؓ只有<span lang="EN-US">4M</span>内存<span lang="EN-US"><br> <br>     for (i=1; i<1024; ++i)<br>         page_dir[i] = 6;<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    // </span><span style="font-size: 12pt; font-family: 宋体;">其他?span lang="EN-US">1023</span>个页目录设|ؓI,如果q?span lang="EN-US">1024</span>w讄Q可讉K<span lang="EN-US">4G</span>内存I间<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    // </span><span style="font-size: 12pt; font-family: 宋体;">讄<span lang="EN-US">0</span>?span lang="EN-US">1M</span>内存为已使用?span lang="EN-US"><br>     for (i=(1*1024*1024)/PAGE_SIZE-1; i>=0; --i)<br>         mmap[i] = PG_REVERSED;<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    // </span><span style="font-size: 12pt; font-family: 宋体;">因ؓ内核只用C低于<span lang="EN-US">1M</span>的内存,所以保留它们,q样׃会被交换出去?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> <br>     __asm__ (<br>         "movl    %%eax,    %%cr3\n\t"        // </span><span style="font-size: 12pt; font-family: 宋体;">加蝲늛录基址到寄存器<span lang="EN-US"><br>         "movl    %%cr0,    %%eax\n\t"<br>         "orl    $0x80000000,    %%eax\n\t"<br>         "movl    %%eax,    %%cr0"::"a"(PAGE_DIR));    // </span>开启分|Ӟ<span lang="EN-US">CR0</span>的最高位<span lang="EN-US"><br> }<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">通过<span lang="EN-US">mmap</span>位图Q我们可以清楚的知道内存的用情况,q样可以分配空闲页帧了Q如下:<span lang="EN-US"><br> <span style="color: red;">08/mm.c</span><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">unsigned int<br> alloc_page(int type) {<br>     int i;<br> <br>     for (i=(sizeof mmap)-1; i>=0 && mmap[i]; --i)<br>         ;<br> <br>     if (i < 0) {<br>         kprintf(KPL_PANIC, "NO MEMORY LEFT");<br>         halt();<br>     }<br>     mmap[i] = type;<br>     return i;            // </span><span style="font-size: 12pt; font-family: 宋体;">q回?span lang="EN-US"><br> }<br> <br> void *<br> page2mem(unsigned int nr) {            // </span>转换拟地址<span lang="EN-US"><br>     return (void *)(nr * PAGE_SIZE);<br> }<br> <br> void<br> do_page_fault(enum KP_LEVEL kl,<br>               unsigned int ret_ip, unsigned int ss, unsigned int gs,<br>               unsigned int fs, unsigned int es, unsigned int ds, <br>               unsigned int edi, unsigned int esi, unsigned int ebp,<br>               unsigned int esp, unsigned int ebx, unsigned int edx, <br>               unsigned int ecx, unsigned int eax, unsigned int isr_nr, <br>               unsigned int err, unsigned int eip, unsigned int cs, <br>               unsigned int eflags,unsigned int old_esp, unsigned int old_ss) {<br>     unsigned int cr2, cr3;<br>     (void)ret_ip; (void)ss; (void)gs; (void)fs; (void)es; <br>     (void)ds; (void)edi; (void)esi; (void)ebp; (void)esp; <br>     (void) ebx; (void)edx; (void)ecx; (void)eax; <br>     (void)isr_nr; (void)eip; (void)cs; (void)eflags; <br>     (void)old_esp; (void)old_ss; (void)kl;<br>     __asm__ ("movl %%cr2, %%eax":"=a"(cr2));<br>     __asm__ ("movl %%cr3, %%eax":"=a"(cr3));<br>     kprintf(KPL_PANIC, "\n  The fault at %x cr3:%x was caused by a %s. "<br>             "The accessing cause of the fault was a %s, when the "<br>             "processor was executing in %s mode, page %x is free\n", <br>             cr2, cr3,<br>             (err&0x1)?"page-level protection voilation":"not-present page", <br>             (err&0x2)?"write":"read", <br>             (err&0x4)?"user":"supervisor",<br>             <span style="color: red;">alloc_page</span>(PG_NORMAL));<br> }<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">异常函敎ͼ它什么也没有做,知识昄一些错误信息?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">现在我们来动态的分配一些内存,我们修改一下Q务函敎ͼ<span lang="EN-US"><br> <span style="color: red;">08/init.c</span><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">static void<br> new_task(unsigned int eip) {<br>     struct TASK_STRUCT *task = <span style="color: red;">page2mem</span>(alloc_page(PG_TASK));<br>     memcpy(&(task->tss), &(TASK0.tss), sizeof(struct TSS_STRUCT));<br> <br>     task->tss.esp0 = (unsigned int)task + PAGE_SIZE;<br>     task->tss.eip = eip;<br>     task->tss.eflags = 0x3202;<br>     task->tss.esp = (unsigned int)<span style="color: red;">page2mem</span>(alloc_page(PG_TASK))+PAGE_SIZE;<br>     task->tss.cr3 = PAGE_DIR;<br>     task->priority = INITIAL_PRIO;<br>     task->ldt[0] = DEFAULT_LDT_CODE;<br>     task->ldt[1] = DEFAULT_LDT_DATA;<br> <br>     task->next = current->next;<br>     current->next = task;<br>     task->state = TS_RUNABLE;<br> }<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">自己分配的Q务数据结构和d堆栈Q是不是很有成就感:Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">最后在<span lang="EN-US">init.c</span>中添加初始化代码Q?span lang="EN-US"><br> <span style="color: red;">08/init.c</span><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">void <br> init(void) {<br>     char wheel[] = {'\\', '|', '/', '-'};<br>     int i = 0;<br> <br>     idt_install();<br>     pic_install();<br>     mm_install();      /* </span><span style="font-size: 12pt; font-family: 宋体;">初始化函数调?span lang="EN-US"> */<br>     kb_install();<br>     timer_install(100);<br>     set_tss((unsigned long long)&TASK0.tss);<br>     set_ldt((unsigned long long)&TASK0.ldt);<br>     __asm__ ("ltrw    %%ax\n\t"::"a"(TSS_SEL));<br>     __asm__ ("lldt    %%ax\n\t"::"a"(LDT_SEL));<br> <br>     kprintf(KPL_DUMP, "Verifing disk partition table....\n");<br>     verify_DPT();<br>     kprintf(KPL_DUMP, "Verifing file systes....\n");<br>     verify_fs();<br>     kprintf(KPL_DUMP, "Checking / directory....\n");<br>     verify_dir();<br> <br>     sti();<br>     new_task((unsigned int)task1_run);<br>     new_task((unsigned int)task2_run);<br>     __asm__ ("movl %%esp,%%eax\n\t" \<br>              "pushl %%ecx\n\t" \<br>              "pushl %%eax\n\t" \<br>              "pushfl\n\t" \<br>              "pushl %%ebx\n\t" \<br>              "pushl $1f\n\t" \<br>              "iret\n" \<br>              "1:\tmovw %%cx,%%ds\n\t" \<br>              "movw %%cx,%%es\n\t" \<br>              "movw %%cx,%%fs\n\t" \<br>              "movw %%cx,%%gs" \<br>              ::"b"(USER_CODE_SEL),"c"(USER_DATA_SEL));<br>     __asm__ ("incb 0xeeffeeff");         /* </span><span style="color: red;">试Q?/span>触发一个异?span lang="EN-US"> */<br>     for (;;) {<br>         __asm__ ("movb    %%al,    0xb8000+160*24"::"a"(wheel[i]));<br>         if (i == sizeof wheel)<br>             i = 0;<br>         else<br>             ++i;<br>     }<br> }<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">异常处理例程中什么也没做Q访问内存出错则LQ?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: red;" lang="EN-US">08/exceptions.c</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">void<br> page_fault(void) {<br>     __asm__ ("pushl    %%eax;call    do_page_fault"::"a"(KPL_PANIC));<br>     halt();<br> }<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">最后把<span lang="EN-US">mm.o </span>d?span lang="EN-US"> Makefile </span>?span lang="EN-US">KERNEL_OBJS </span>中去Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: red;" lang="EN-US">08/Makefile</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">KERNEL_OBJS= load.o init.o isr.o timer.o libcc.o scr.o kb.o task.o kprintf.o hd.o exceptions.o fs.o mm.o<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p><img src ="http://www.shnenglu.com/jinglexy/aggbug/25801.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-06-08 08:44 <a href="http://www.shnenglu.com/jinglexy/archive/2007/06/08/25801.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(W?课:文gpȝQ(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/05/19/24377.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Sat, 19 May 2007 03:35:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/05/19/24377.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/24377.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/05/19/24377.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/24377.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/24377.html</trackback:ping><description><![CDATA[     摘要: W?课:文gpȝ    下蝲源代?声明Q{载请保留Q?译者:http://www.shnenglu.com/jinglexy 原作者:xiaoming.mo at skelix dot org MSN & Email: jinglexy at yahoo dot com dot cn     目标   q一课中Q?..  <a href='http://www.shnenglu.com/jinglexy/archive/2007/05/19/24377.html'>阅读全文</a><img src ="http://www.shnenglu.com/jinglexy/aggbug/24377.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-05-19 11:35 <a href="http://www.shnenglu.com/jinglexy/archive/2007/05/19/24377.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(W?课:多Q务)Q原创)http://www.shnenglu.com/jinglexy/archive/2007/05/15/24158.html天衣有缝天衣有缝Tue, 15 May 2007 08:55:00 GMThttp://www.shnenglu.com/jinglexy/archive/2007/05/15/24158.htmlhttp://www.shnenglu.com/jinglexy/comments/24158.htmlhttp://www.shnenglu.com/jinglexy/archive/2007/05/15/24158.html#Feedback3http://www.shnenglu.com/jinglexy/comments/commentRss/24158.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/24158.html阅读全文

天衣有缝 2007-05-15 16:55 发表评论
]]>
自己动手写内核(W?课:中断和异?Q(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/05/11/23881.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Fri, 11 May 2007 02:39:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/05/11/23881.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/23881.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/05/11/23881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/23881.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/23881.html</trackback:ping><description><![CDATA[     摘要: W?课:中断和异?      下蝲源代? 声明Q{载请保留Q?译者:http://www.shnenglu.com/jinglexy 原作者:xiaoming.mo at skelix dot org MSN & Email: jinglexy at yahoo dot com dot cn 目标 在上一节课中,我们?..  <a href='http://www.shnenglu.com/jinglexy/archive/2007/05/11/23881.html'>阅读全文</a><img src ="http://www.shnenglu.com/jinglexy/aggbug/23881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-05-11 10:39 <a href="http://www.shnenglu.com/jinglexy/archive/2007/05/11/23881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>整理一些有用的|页Q原创)http://www.shnenglu.com/jinglexy/archive/2007/05/09/23727.html天衣有缝天衣有缝Wed, 09 May 2007 13:01:00 GMThttp://www.shnenglu.com/jinglexy/archive/2007/05/09/23727.htmlhttp://www.shnenglu.com/jinglexy/comments/23727.htmlhttp://www.shnenglu.com/jinglexy/archive/2007/05/09/23727.html#Feedback0http://www.shnenglu.com/jinglexy/comments/commentRss/23727.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/23727.html 

一?/span>solaris 内核及应用程序源E序Q?/span>

http://src.opensolaris.org/source          主页

http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/ls/ls.c   范例Q?/span>ls源程?/span>

 

二、比较多?/span>gcc资料

http://gcc.cookys.org/

 

三?/span>linux内核交叉引用Q从0.1?.0Q?.0Q?.2Q?.4Q?/span>2.6.20都有

http://lxr.linux.no/source/

http://www.oldlinux.org/lxr/http/source/

 

四?/span>C 语言常见问题?/span>(中英?/span>)

http://c-faq-chn.sourceforge.net/

http://c-faq.com/

 

五、操作系l相关的一些资料,包括linux源程序分?/span>

http://osdev.gro.clinux.org

 

六?/span>linus自传

http://www.bookcool.com/online/zhuanji/happyking-gb/0/content.htm

 

七、嵌入式及OS开发资料(英文Q?/span>

http://my.execpc.com/~geezer/

 

八?/span>Testing and debugging KOSQ英文)

http://kos.enix.org/~d2/snapshots/kos_current/doc/testingen-html

 

九?/span>the Single UNIX Specification Version 3Q推荐:可作?/span>posix的替代参考资料)

http://www.unix.org/single_unix_specification

 

十?/span>OS设计参考(英文Q?/span>

http://www.nondot.org/~sabre/os/articles

 



天衣有缝 2007-05-09 21:01 发表评论
]]>
自己动手写内核(W?课:中断和异?Q(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23600.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Mon, 07 May 2007 23:37:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23600.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/23600.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23600.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/23600.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/23600.html</trackback:ping><description><![CDATA[     摘要: W?课:中断和异? 声明Q{载请保留Q?译者:http://www.shnenglu.com/jinglexy 原作者:xiaoming.mo at skelix dot org MSN & Email: jinglexy at yahoo dot com dot cn 目标        &nb...  <a href='http://www.shnenglu.com/jinglexy/archive/2007/05/08/23600.html'>阅读全文</a><img src ="http://www.shnenglu.com/jinglexy/aggbug/23600.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-05-08 07:37 <a href="http://www.shnenglu.com/jinglexy/archive/2007/05/08/23600.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(W?课:辅助函数Q(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23599.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Mon, 07 May 2007 23:36:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23599.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/23599.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23599.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/23599.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/23599.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">W?span lang="EN-US">3</span>课:辅助函数<span lang="EN-US"><o:p></o:p></span></span></p> <br> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">声明Q{载请保留</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Q?/span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"></span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">译?/span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Q?/span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">http://www.shnenglu.com/jinglexy</span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">原作者:</span>xiaoming.mo at skelix dot org</p> MSN & Email: jinglexy at yahoo dot com dot cn<br><br> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">目标<span lang="EN-US">            <a target="_blank"><span lang="EN-US"><span lang="EN-US">下蝲源程?/span></span></a><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">q节课我们讲q的内容与操作系l暂无太大关p,但是q些基础函数非常重要Qƈ且在后面的课E中l常用到。这是我们l常听到的内核库。如果你对这些不是很感兴,知道<span lang="EN-US">kprintf</span>?span lang="EN-US">c</span>语言里面?span lang="EN-US">print</span>一样工作就行了。简单掠q即可?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> <a name="kprintf"></a> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">C</span><span style="font-size: 12pt; font-family: 宋体;">用户库里面的<span lang="EN-US">printf</span>h高度可׾~性,也很Ҏ理解Q相比之?span lang="EN-US">C</span>Q+中的<span lang="EN-US">IO</span>q算W就比较难了。ؓ了在屏幕上显C字W串或数据,我们现在需要实现类?span lang="EN-US">C</span>库中?span lang="EN-US">printf</span>Q显C字W在<span lang="EN-US">B8000</span>开始的昑֭处。我q不像完全实?span lang="EN-US">printf</span>的所有功能,因ؓ<span lang="EN-US">skelix</span>内核只需要显C字W串Q十q制和十六进制或二进Ӟ正整敎ͼ字符p了,q且需要支持可变参数。其他更高的功能我们不会用到?span lang="EN-US"><br> <br> </span>q里有一U方法来实现Q我们直到象<span lang="EN-US">func(int arg1, int arg2, int arg3)</span>q样一个函数被调用Ӟ它汇~后的指令应该如下(所有从左向叛_栈的~译器应该从地球上彻底消失)Q?span lang="EN-US"><br> pushl   arg3<br> pushl   arg2<br> pushl   arg1<br> call    func<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们看到Q参C叛_左一个个入栈Q参数越多,入栈深。如果是可变参数那我们怎么知道有多个参数呢?{案?span lang="EN-US">printf</span>格式化字W串中参数判断:有多个<span lang="EN-US">%X</span>Q就有多个参数要解析。在<span lang="EN-US">32</span>位模式下Q所有小?span lang="EN-US">4</span>字节的参数都被当?span lang="EN-US">4</span>字节处理。例如一?span lang="EN-US">char</span>型参敎ͼ入栈时就?span lang="EN-US">int</span>型了Q所以在解析参数时务必保证正?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们q样设计<span lang="EN-US">kprintf</span>参数Q?span lang="EN-US">kprintf(color, format string, arguments...)<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">W一个参数定义输出的前景<span lang="EN-US">/</span>背景颜色。我们定义了很多宏来解析栈,如果你熟?span lang="EN-US">C</span>语言应该很容易理解它们?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> <span style="color: red;">03/kprintf.c</span><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">#define args_list char *            // </span><span style="font-size: 12pt; font-family: 宋体;">q个宏用例{换栈I间为字W串指针<span lang="EN-US"><br> #define _arg_stack_size(type)    (((sizeof(type)-1)/sizeof(int)+1)*sizeof(int))<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">                                    // </span><span style="font-size: 12pt; font-family: 宋体;">q个宏四舍五入参数大ؓ<span lang="EN-US">4</span>字节的倍数<span lang="EN-US"><br> #define args_start(ap, fmt) do {    \<br> ap = (char *)((unsigned int)&fmt + _arg_stack_size(&fmt));   \<br> } while (0)<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">                                    // </span><span style="font-size: 12pt; font-family: 宋体;">参数从格式化字W串后面开始解析,?span lang="EN-US">fmt</span>是栈顶Q上面这个宏是取参数的首地址<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> #define args_end(ap)                // </span><span style="font-size: 12pt; font-family: 宋体;">到现在ؓ止,什么也不做<span lang="EN-US"><br> #define args_next(ap, type) (((type *)(ap+=_arg_stack_size(type)))[-1])<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">                                    // </span><span style="font-size: 12pt; font-family: 宋体;">?span lang="EN-US">‘</span>当前<span lang="EN-US">’</span>参数地址Q然后设|指针ؓ下一个参数地址Q暧昧的函数名!<span lang="EN-US"><br> <br> <span style="color: red;">03/kprintf.c</span><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">static char buf[1024] = {-1};       // </span><span style="font-size: 12pt; font-family: 宋体;">注意没有锁保护,引用该变量的函数不可重入Q?span lang="EN-US"><br> static int ptr = -1;<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">下面两个函数解析gؓ指定的进制数Q?span lang="EN-US"><br> static void<br> parse_num(unsigned int value, unsigned int base) {            // </span>可以打印于{于<span lang="EN-US">10</span>q制的数<span lang="EN-US"><br>     unsigned int n = value / base;<br>     int r = value % base;<br>     if (r < 0) {<br>         r += base;<br>         --n;<br>     }<br>     if (value >= base)<br>         parse_num(n, base);<br>     buf[ptr++] = (r+'0');<br> }<br> <br> static void                                                   // </span>打印<span lang="EN-US">16</span>q制?span lang="EN-US"><br> parse_hex(unsigned int value) {<br>     int i = 8;<br>     while (i-- > 0) {<br>         buf[ptr++] = "0123456789abcdef"[(value>>(i*4))&0xf];<br>     }<br> }<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">现在我们来看一?span lang="EN-US"> kprintf</span>q个函数Q它支持的格式:<span lang="EN-US">%s, %c, %x, %d, %%<br> void<br> kprintf(enum KP_LEVEL kl, const char *fmt, ...) {<br>     int i = 0;<br>     char *s;<br>     /* must be the same size as enum KP_LEVEL */<br>     struct KPC_STRUCT {<br>         COLOUR fg;<br>         COLOUR bg;<br>     } KPL[] = {<br>         {BRIGHT_WHITE, BLACK},<br>         {YELLOW, RED},<br>     };<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> enum KP_LEVEL {KPL_DUMP, KPL_PANIC} </span><span style="font-size: 12pt; font-family: 宋体;">定义?span lang="EN-US"> include/kprintf.h, </span>它表CZU输出方?span lang="EN-US">, KPL_DUMP </span>使用黑色背景白色前景昄字符Q?span lang="EN-US">KPL_PANIC </span>使用黄色前景和红色背景。颜色常量定义在<span lang="EN-US"> include/scr.h, </span>后面会介l到<span lang="EN-US">.<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    args_list args;<br>     args_start(args, fmt);<br> <br>     ptr = 0;<br> <br>     for (; fmt[i]; ++i) {<br>         if ((fmt[i]!='%') && (fmt[i]!='\\')) {<br>             buf[ptr++] = fmt[i];<br>             continue;<br>         } else if (fmt[i] == '\\') {<br>             /* \a \b \t \n \v \f \r \\ */<br>             switch (fmt[++i]) {<br>             case 'a': buf[ptr++] = '\a'; break;<br>             case 'b': buf[ptr++] = '\b'; break;<br>             case 't': buf[ptr++] = '\t'; break;<br>             case 'n': buf[ptr++] = '\n'; break;<br>             case 'r': buf[ptr++] = '\r'; break;<br>             case '\\':buf[ptr++] = '\\'; break;<br>             }<br>             continue;<br>         }<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">        /* </span><span style="font-size: 12pt; font-family: 宋体;">下面是支持的打印格式<span lang="EN-US"> */<br>         switch (fmt[++i]) {<br>         case 's':<br>             s = (char *)args_next(args, char *);<br>             while (*s)<br>                 buf[ptr++] = *s++;<br>             break;<br>         case 'c':<br>             buf[ptr++] = (char)args_next(args, int);<br>             break;<br>         case 'x':<br>             parse_hex((unsigned long)args_next(args, unsigned long));<br>             break;<br>         case 'd':<br>             parse_num((unsigned long)args_next(args, unsigned long), 10);<br>             break;<br>         case '%':<br>             buf[ptr++] = '%';<br>             break;<br>         default:<br>             buf[ptr++] = fmt[i];<br>             break;<br>         }<br>     }<br>     buf[ptr] = '\0';<br>     args_end(args);<br>     for (i=0; i<ptr; ++i)<br>         <span style="color: red;">print_c</span>(buf[i], KPL[kl].fg, KPL[kl].bg);            /* print_c() </span>是下层的昄函数Q本文后面会有讲?span lang="EN-US"> */<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">}<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br>  <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">׃是内核程序,我们无法使用<span lang="EN-US">C</span>用户库。所以一?span lang="EN-US">memcpy</span>Q?span lang="EN-US">memset</span>Q?span lang="EN-US">memcpy</span>函数需要自己实玎ͼ但是需要注意的是在<span lang="EN-US">BSD</span>pȝ中,即便使用?span lang="EN-US">-nostdlib</span>Q编译器仍然会?span lang="EN-US">System V</span>中相关的<span lang="EN-US">memcpy</span>{代码,具体情况我也不是很清除。这些函数的效率当然无法?span lang="EN-US">linux</span>内核中的内嵌汇编相比Q我们暂时这样实现它们吧?span lang="EN-US"><br> <span style="color: red;">03/libcc.c</span><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">/* </span><span style="font-size: 12pt; font-family: 宋体;">下面函数寚w叠区域也q行了处?span lang="EN-US"> */<br> void <br> bcopy(const void *src, void *dest, unsigned int n) {<br>     const char *s = (const char *)src;<br>     char *d = (char *)dest;<br>     if (s <= d)<br>         for (; n>0; --n)<br>             d[n-1] = s[n-1];<br>     else<br>         for (; n>0; --n)<br>             *d++ = *s++;<br> }<br> <br> void<br> bzero(void *dest, unsigned int n) {<br>     memset(dest, 0, n);<br> }<br> <br> void *<br> memcpy(void *dest, const void *src, unsigned int n) {<br>     bcopy(src, dest, n);<br>     return dest;<br> }<br> <br> void *<br> memset(void *dest, int c, unsigned int n) {<br>     char *d = (char *)dest;<br>     for (; n>0; --n)<br>         *d++ = (char)c;<br>     return dest;<br> }<br> <br> int<br> memcmp(const void *s1, const void *s2, unsigned int n) {<br>     const char *s3 = (const char *)s1;<br>     const char *s4 = (const char *)s2;<br>     for (; n>0; --n) {<br>         if (*s3 > *s4)<br>             return 1;<br>         else if (*s3 < *s4)<br>             return -1;<br>         ++s3;<br>         ++s4;<br>     }<br>     return 0;<br> }<br> <br> int<br> strcmp(const char *s1, const char *s2) {<br>     while (*s1 && *s2) {<br>         int r = *s1++ - *s2++;<br>         if (r)<br>             return r;<br>     }<br>     if (*s1 == *s2)<br>         return 0<br>     else<br>         return (*s1)?1:-1;<br> }<br> <br> char *<br> strcpy(char *dest, const char *src) {<br>     char *p = dest;<br>     while ( (*dest++ = *src++))<br>         ;<br>     *dest = 0;<br>     return p;<br> }<br> <br> unsigned int<br> strlen(const char *s) {<br>     unsigned int n = 0;<br>     while (*s++)<br>         ++n;<br>     return n;<br> }<br> <br> <a name="print_c"></a><span style="color: red;">print_c</span></span><span style="color: red;">函数</span><span lang="EN-US"><br> </span>直接操作昑֭区域一点也不方便,所以我们需要一个显C模块。这个就是我们的<span lang="EN-US">‘</span>昑֍驱动<span lang="EN-US">’</span>了,是不是不敢相信驱动是q么单的事情Q我们先来看一下一些常量定义:<span lang="EN-US"><br> <span style="color: red;">03/include/scr.h</span><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">#define MAX_LINES    25                // bios</span><span style="font-size: 12pt; font-family: 宋体;">默认讄屏幕?span lang="EN-US"> 80x25</span>大小Q彩色字W模?span lang="EN-US"><br> #define MAX_COLUMNS  80<br> #define TAB_WIDTH    8                 // </span>必须是:<span lang="EN-US">2^n<br> #define VIDEO_RAM    0xb8000           // </span>昑֭地址<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们曄要提到过q个地址Q在字符模式下,适配器?span lang="EN-US">0xB8000-0xBF000</span>作ؓ视频内存。通常我们处于<span lang="EN-US">80x25</span>大小屏幕Q有<span lang="EN-US">16</span>U颜艌Ӏ由于一个屏q只需?span lang="EN-US">80x25x2</span>个字节,?span lang="EN-US">4k</span>Q所以该视频内存可以分ؓ多个c我们用所有的,但是当前只能有一个页面可见。ؓ了显CZ个字W,用?span lang="EN-US">2</span>个字节,一个字节是字符|另一个字节是字符属性(即颜Ԍ。属性字节定义如下:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">To display a single character, two bytes are being used which called the character byte and the attribute byte. The character byte contains the value of the character. The attribute byte is defined like this: <o:p></o:p></span></p> <table class="MsoNormalTable" style="width: 51.76%;" border="1" cellpadding="0" width="51%"> <tbody> <tr> <td style="padding: 1.5pt; width: 99pt;" width="132"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bit 7<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 600.75pt;" width="801"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">闪烁<span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 99pt;" width="132"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bits 6-4<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 600.75pt;" width="801"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">背景?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 99pt;" width="132"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bit 3<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 600.75pt;" width="801"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">明亮模式<span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> <tr> <td style="padding: 1.5pt; width: 99pt;" width="132"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Bit3 2-0<o:p></o:p></span></p> </td> <td style="padding: 1.5pt; width: 600.75pt;" width="801"> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">前景?span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> </tbody> </table> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">#define LINE_RAM    (MAX_COLUMNS*2)<br> #define PAGE_RAM    (MAX_LINE*MAX_COLUMNS)<br> <br> #define BLANK_CHAR    (' ')<br> #define BLANK_ATTR    (0x70)        /* </span><span style="font-size: 12pt; font-family: 宋体;">白色前景Q黑色背?span lang="EN-US"> */<br> <br> #define CHAR_OFF(x,y)    (LINE_RAM*(y)+2*(x))        /* </span>计算l定坐标<span lang="EN-US">x</span>Q?span lang="EN-US">y</span>的偏Ud址Q相?span lang="EN-US">0xB8000</span>Q?span lang="EN-US"> */<br> Calculates the offset of a given ordinary x, y from 0xB8000<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">typedef enum COLOUR_TAG {                            /* </span><span style="font-size: 12pt; font-family: 宋体;">颜色?span lang="EN-US"> */<br>     BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, WHITE,<br>     GRAY, LIGHT_BLUE, LIGHT_GREEN, LIGHT_CYAN, <br>     LIGHT_RED, LIGHT_MAGENTA, YELLOW, BRIGHT_WHITE<br> } COLOUR;<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">坐标pd下:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">  ___________________\<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> | </span><span style="font-size: 12pt; font-family: 宋体;">Q?span lang="EN-US">0</span>Q?span lang="EN-US">0</span>Q?span lang="EN-US">          /<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> |<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">\|/<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> <br> <span style="color: red;">03/scr.c</span><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">static int csr_x = 0;<br> static int csr_y = 0;<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">׃我们只用C一个视频页Q所以上面两个变量就可以存储坐标了。关于多|C可以在|络上查扄兌料?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> static void <br> scroll(int lines) {        </span><span style="font-size: 12pt; font-family: 宋体;">向上滚动屏幕多少行,是一些内存复写?span lang="EN-US"><br>     short *p = (short *)(VIDEO_RAM+CHAR_OFF(MAX_COLUMNS-1, MAX_LINES-1));<br>     int i = MAX_COLUMNS-1;<br>     memcpy((void *)VIDEO_RAM, (void *)(VIDEO_RAM+LINE_RAM*lines),<br>            LINE_RAM*(MAX_LINES-lines));<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br>     for (; i>=0; --i)            // </span><span style="font-size: 12pt; font-family: 宋体;">说明q个<span lang="EN-US">for</span>循环有问题,觉得应该Ҏ下面q样Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    // for (i = i * lines; i>=0; --i)<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">        *p-- = (short)((BLANK_ATTR<<4)|BLANK_CHAR);<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">}<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">下面函数讄光标可能会引发竞态条Ӟ但是<span lang="EN-US">print_c</span>只准备在内核中用,所以没有关中断。它可能会引起一?span lang="EN-US">bug</span>Q但是我没有扑ֈ。译注:全局变量没有锁保护在设计上就是一U错误。这里的代码保护实是没有做Q读者应用到自己的内核时要小心了?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">void <br> set_cursor(int x, int y) {<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    csr_x = x;<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    csr_y = y;<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    outb(0x0e, 0x3d4);                                   </span><span style="font-size: 12pt; font-family: 宋体;">讄光标?span lang="EN-US">8</span>位的准备工作<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    outb(((csr_x+csr_y*MAX_COLUMNS)>>8)&0xff, 0x3d5);    </span><span style="font-size: 12pt; font-family: 宋体;">讄光标?span lang="EN-US">8</span>?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    outb(0x0f, 0x3d4);                                   </span><span style="font-size: 12pt; font-family: 宋体;">讄光标?span lang="EN-US">8</span>位的准备工作<span lang="EN-US"><br>     outb(((csr_x+csr_y*MAX_COLUMNS))&0xff, 0x3d5);       </span>讄光标?span lang="EN-US">8</span>?span lang="EN-US">   <br> }<br> <br> void<br> get_cursor(int *x, int *y) {<br>     *x = csr_x;<br>     *y = csr_y;<br> }<br> <br> void <br> print_c(char c, COLOUR fg, COLOUR bg) {<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">// </span><span style="font-size: 12pt; font-family: 宋体;">用这个函数来昄一个具体的字符到屏q,我们可以把它看作<span lang="EN-US">‘</span>昑֍驱动<span lang="EN-US">’<br>     char *p; <br>     char attr;<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br>     p = (char *)VIDEO_RAM+CHAR_OFF(csr_x, csr_y);        // </span><span style="font-size: 12pt; font-family: 宋体;">取光标位|?span lang="EN-US"><br>     attr = (char)(bg<<4|fg);                             // </span>属?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">    switch (c) {<br>     case '\r':<br>         csr_x = 0;<br>         break;<br>     case '\n':<br>         for (; csr_x<MAX_COLUMNS; ++csr_x) {<br>             *p++ = BLANK_CHAR;<br>             *p++ = attr;<br>         }<br>         break;<br>     case '\t':<br>         c = csr_x+TAB_WIDTH-(csr_x&(TAB_WIDTH-1));<br>         c = c<MAX_COLUMNS?c:MAX_COLUMNS;<br>         for (; csr_x<c; ++csr_x) {<br>             *p++ = BLANK_CHAR;<br>             *p++ = attr;<br>         }<br>         break;<br>     case '\b':<br>         if ((! csr_x) && (! csr_y))<br>             return;<br>         if (! csr_x) {<br>             csr_x = MAX_COLUMNS - 1;<br>             --csr_y;<br>         } else<br>             --csr_x;<br>         ((short *)p)[-1] = (short)((BLANK_ATTR<<4)|BLANK_CHAR);<br>         break;<br>     default:<br>         *p++ = c; <br>         *p++ = attr;<br>         ++csr_x;<br>         break;<br>     }<br>     if (csr_x >= MAX_COLUMNS) {<br>         csr_x = 0;<br>         if (csr_y < MAX_LINES-1)<br>             ++csr_y;<br>         else <br>             scroll(1);<br>     }<br>     set_cursor(csr_x, csr_y);        // </span><span style="font-size: 12pt; font-family: 宋体;">讄光标位置<span lang="EN-US"><br> }<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">函数比较单,没有分析的必要了Q大家自q吧?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> </span></p><img src ="http://www.shnenglu.com/jinglexy/aggbug/23599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-05-08 07:36 <a href="http://www.shnenglu.com/jinglexy/archive/2007/05/08/23599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(W?课:保护模式Q(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23598.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Mon, 07 May 2007 23:35:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23598.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/23598.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23598.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/23598.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/23598.html</trackback:ping><description><![CDATA[     摘要: W?课:保护模式 声明Q{载请保留Q?译者:http://www.shnenglu.com/jinglexy 原作者:xiaoming.mo at skelix dot org MSN & Email: jinglexy at yahoo dot com dot cn 目标        下蝲源程?..  <a href='http://www.shnenglu.com/jinglexy/archive/2007/05/08/23598.html'>阅读全文</a><img src ="http://www.shnenglu.com/jinglexy/aggbug/23598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-05-08 07:35 <a href="http://www.shnenglu.com/jinglexy/archive/2007/05/08/23598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(W?课:引导E序Q(原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23597.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Mon, 07 May 2007 23:34:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23597.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/23597.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/05/08/23597.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/23597.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/23597.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">W?span lang="EN-US">1</span>课:引导E序<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">声明Q{载请保留</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Q?/span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"></span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">译?/span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Q?/span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">http://www.shnenglu.com/jinglexy</span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">原作者:</span>xiaoming.mo at skelix dot org</p> MSN & Email: jinglexy at yahoo dot com dot cn<br><br><br> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: blue;">目标Q?/span><span style="font-size: 12pt; font-family: 宋体;">?span lang="EN-US">"system"</span>从Y盘启动,q打?span lang="EN-US">"Hello World!" <a target="_blank"><span lang="EN-US"><span lang="EN-US">下蝲源程?/span></span></a><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: blue;">内存d</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">处理器以<span lang="EN-US">‘</span>字节<span lang="EN-US">’</span>理和访问内存,每个字节都有独立的地址Q即物理地址。有两种地址映射方式Q分D和分页Q?span lang="EN-US">skelix</span>内核中都用到了?a name="Memory_Addressing"></a> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> </span><span style="font-size: 12pt; font-family: 宋体;">D对于我们来说再熟悉不过了,先回一?span lang="EN-US">dos</span>时期的段吧。它是一?span lang="EN-US">16</span>位的寄存器,所以最多可以直接访?span lang="EN-US">2^16</span>字节的内存,?span lang="EN-US">64K</span>。这对应用程序来说太了Q于?span lang="EN-US">Intel</span>使用<span lang="EN-US">Segment:Offset</span>l合方式来表CZ个虚拟地址。段寄存器左U?span lang="EN-US">4</span>位加上偏Ud得到实际的物理地址了。例如,<span lang="EN-US">0x<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7c</st1:chmetcnv>00:0x0189</span>表示物理地址<span lang="EN-US">0x<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7c</st1:chmetcnv>189</span>Q而不?span lang="EN-US">0x<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7c</st1:chmetcnv>000189</span>。计过E如下:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7C</st1:chmetcnv>000<br> + 0189<br> -------<br>  <st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7C</st1:chmetcnv>189<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">现在我们来计最大可以访问的地址Q?span lang="EN-US">FFFF:FFFF<br> <br>  FFFF0<br> + FFFF<br> -------<br> 10FFEF<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">q个范围?st1:chmetcnv unitname="m" sourcevalue="1" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US">1M</span></st1:chmetcnv><span lang="EN-US"> + 65519 bytes, </span>因ؓ?span lang="EN-US">80386</span>中用了<span lang="EN-US">20</span>位地址U,所以可以额外多讉K<span lang="EN-US">65519</span>个字节虚拟地址Q例如地址<span lang="EN-US">0x100010</span>被映到地址<span lang="EN-US">0x10</span>Q访问这两个地址是等L?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">表示同一个物理地址有多U方式,例如<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US">07C</span></st1:chmetcnv><span lang="EN-US">0:0000</span>?span lang="EN-US">0000:<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7C</st1:chmetcnv>00 </span>是一L?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">另一个概忉|U性地址Q这个是<span lang="EN-US">32</span>位地址Q只有当分页机制开启时才有效,文章后面会提到它?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: blue;">引导q程</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">当系l上甉|<span lang="EN-US">RESET</span>Ӟ处理器将执行一些列的初始化Q寄存器被设|成非预知状态,q且<span lang="EN-US">cpu</span>处于实模式。也怽想知?span lang="EN-US">cpu</span>是怎样讄<span lang="EN-US">segment:offset</span>为物理地址<span lang="EN-US">FFFF0</span>的(<span lang="EN-US">0xf000:0xfff0</span>是<span lang="EN-US">bios</span>入口地址Q,q是因ؓ<span lang="EN-US">cs</span>寄存器有一个非可见部分Q它保存?span lang="EN-US">ffff:0000</span>地址Qƈ?span lang="EN-US">cs</span>在初始化时会被装?span lang="EN-US">f000</span>倹{此后以正常方式使用它。当<span lang="EN-US">bois</span>取得控制权后Q根据用户配|(从Y驱,盘Q或<span lang="EN-US">cdrom</span>Q中dW一?span lang="EN-US">sector</span>?st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US">00007C</span></st1:chmetcnv><span lang="EN-US">00</span>Qƈ跌{到该地址执行Q就是引导程?span lang="EN-US">bootstrap</span>Q。在<span lang="EN-US">bootstrap</span>中我们可以?span lang="EN-US">bios</span>中断Q但是进?span lang="EN-US">kernel</span>后就不能再用了?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> </span><span style="font-size: 12pt; font-family: 宋体; color: blue;">E序一Q?span lang="EN-US">as</span>?span lang="EN-US">ld</span>的范?/span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">你可以在下蝲源程序的<span style="color: red;" lang="EN-US">01/first.cry/bootsect.s</span><span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">        .text              .text</span><span style="font-size: 12pt; font-family: 宋体;">表示代码D?span lang="EN-US"><br>         .globl             start</span>表示<span lang="EN-US">start</span>可以用作外部W号<span lang="EN-US"><br>         .code16            GCC</span>默认使用<span lang="EN-US">32</span>位地址和操作数Q这里告诉它使用<span lang="EN-US">16</span>?span lang="EN-US"><br> start:<br>         jmp      start     </span>d@?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">.org    0x1fe,   0x90      <span style="color: blue;">.org NEW-LC, FILL</span></span><span style="font-size: 12pt; font-family: 宋体; color: blue;">Q?/span><span style="font-size: 12pt; font-family: 宋体; color: black;">说明Q这里填?span lang="EN-US">0x90</span>Q是<span lang="EN-US">nop</span>指o的机器码<span lang="EN-US"><br> </span></span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">.word   0xaa55<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">讲解Q?span lang="EN-US">.org</span>指o指示下一个数据地址Qؓ了编译这个程序,我们写了一?span lang="EN-US">Makefile</span>QM能老是敲命令吧Q呵c?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">|络上可以找到很多写<span lang="EN-US">Makefile</span>的资料,~译选项才是我们x的焦炏V?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br> <span style="color: red;">01/first.cry/Makefile</span><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">AS=as                     gcc</span><span style="font-size: 12pt; font-family: 宋体;">汇编工具<span lang="EN-US"><br> LD=ld                     gcc</span>q接?span lang="EN-US"><br> <br> .s.o:<br>     ${AS} -a $< -o $*.o >$*.map<br> <br> all: final.img<br> <br> final.img: bootsect<br>     mv bootsect final.img<br> <br> bootsect: bootsect.o<br>     ${LD} --oformat binary -N -e start -Ttext 0x<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7c</st1:chmetcnv>00 -o bootsect $<<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">讲解Q?span lang="EN-US">ld</span>可以被配|ؓ支持多于一U的目标文g<span lang="EN-US">. binary</span>表示没有E序头和其他信息Q仅仅是一些裸数据。如果没有这个选项Q将被默认链接ؓ<span lang="EN-US">elf</span>格式?span lang="EN-US">-N</span>?span lang="EN-US">text</span>?span lang="EN-US">data</span>节设|ؓ可读写?span lang="EN-US">-Ttext</span>?span lang="EN-US">text</span>节v始地址讄?span lang="EN-US">0x<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7c</st1:chmetcnv>00</span>Q在<span lang="EN-US">jmp</span>和数据引用等重定位链接时会用到这个参考|Q所有的引用地址都是?st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on"><span lang="EN-US">7c</span></st1:chmetcnv><span lang="EN-US">00</span>q个地址上加出来的?span lang="EN-US">-e</span>选项指定E序入口?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">现在我们q行<span lang="EN-US">make</span>指o~译一下:<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">[root@root~/source/os/skelix/01/first.cry]$ ls<br> <span style="color: green;">bootsect.s  COPYING  Makefile</span><br> [root@root~/source/os/skelix/01/first.cry]$ make<br> as -a bootsect.s -o bootsect.o >bootsect.map<br> ld --oformat binary -N -e start -Ttext 0x<st1:chmetcnv unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">7c</st1:chmetcnv>00 -o bootsect bootsect.o<br> mv bootsect final.img<br> [root@root~/source/os/skelix/01/first.cry]$ ls<br> <span style="color: green;">bootsect.map  bootsect.o </span> bootsect.s  COPYING  <span style="color: green;">final.img</span>  Makefile<br> [root@root~/source/os/skelix/01/first.cry]$<o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">现在Q我们启?span lang="EN-US">vmware</span>Q运行,载入软驱映象文g<span lang="EN-US">"final.img"</span>Q我们得C个黑屏,q是正确的,因ؓ我们什么也没有做?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: blue;">E序一Q显C?<span lang="EN-US">Hello World!</span></span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">好了Q上面的黑屏E序q不是太好玩Q现在我们尝试在上面打印<span lang="EN-US">"Hello World!"<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体; color: red;" lang="EN-US">01/hello.world/bootsect.s</span><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">        .text<br>         .globl  start<br>         .code16<br> start:<br>         jmp     code<br> msg:                                   </span><span style="font-size: 12pt; font-family: 宋体;">使用<span lang="EN-US">jmp</span>指o跌该变量,q是我们Z么在<span lang="EN-US">Makefile</span>使用<span lang="EN-US">-N</span>链接选项?span lang="EN-US"><br>         .string "Hello World!\x0"<br> code:<br>         movw    $0xb800,%ax<br>         movw    %ax,    %es            es</span>D设|成<span lang="EN-US">B800</span>Q如前所qͼ<span lang="EN-US">segment:offset</span>地址映射方式Q它指向<span lang="EN-US">B8000</span>Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">                                       </span><span style="font-size: 12pt; font-family: 宋体;">q意味着W一个字节地址?span lang="EN-US">0</span>Q映到<span lang="EN-US">B8000</span>Q,属性字节是<span lang="EN-US">1</span>Q映到<span lang="EN-US">B8001</span>Q?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">                                       B8001</span><span style="font-size: 12pt; font-family: 宋体;">D|ؓ<span lang="EN-US">0x07</span>可以这?span lang="EN-US">byte</span>颜色讄为黑底白字?span lang="EN-US"><br>         xorw    %ax,    %ax<br>         movw    %ax,    %ds<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">        movw    $msg,   %si            </span><span style="font-size: 12pt; font-family: 宋体;">?span lang="EN-US">movsb</span>指o讄正确?span lang="EN-US">si</span>?span lang="EN-US">di<br>         xorw    %di,    %di<br>         cld<br>         movb    $0x07,  %al            </span>字的颜色<span lang="EN-US"><br> <br> 1:<br>         cmp     $0,    (%si)<br>         je      <st1:chmetcnv unitname="F" sourcevalue="1" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">1f</st1:chmetcnv>    <br>         movsb<br>         stosb<br>         jmp     1b<br> 1:      jmp     1b<br> <br> .org    0x1fe,  0x90<br> .word   0xaa55<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> </span></p><img src ="http://www.shnenglu.com/jinglexy/aggbug/23597.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-05-08 07:34 <a href="http://www.shnenglu.com/jinglexy/archive/2007/05/08/23597.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己动手写内核(环境)Q原创) http://www.shnenglu.com/jinglexy/archive/2007/05/08/23596.html天衣有缝天衣有缝Mon, 07 May 2007 23:32:00 GMThttp://www.shnenglu.com/jinglexy/archive/2007/05/08/23596.htmlhttp://www.shnenglu.com/jinglexy/comments/23596.htmlhttp://www.shnenglu.com/jinglexy/archive/2007/05/08/23596.html#Feedback0http://www.shnenglu.com/jinglexy/comments/commentRss/23596.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/23596.htmlW?span lang="EN-US">0课:环境需?span lang="EN-US">

声明Q{载请保留Q?/span>

译?/span>Q?/span>http://www.shnenglu.com/jinglexy

原作者:xiaoming.mo at skelix dot org

MSN & Email: jinglexy at yahoo dot com dot cn

GCC
Skelix
使用c语言~写Q当然也用了汇编语言Q?span lang="EN-US">at&t风格Q,?span lang="EN-US">linux下?span lang="EN-US">gcc~译?span lang="EN-US">

[root@root ~]$ gcc -v
Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)

在每教E中都给Z源程序和软盘映象文gQ你可以直接使用它们。如果你需要编译这些源E序Q编译环境必L。我们推荐的环境?span lang="EN-US">linux2.6.x内核Q?span lang="EN-US">gcc3.x~译器?span lang="EN-US">

׃在源E序中用了__asm__, __attribute__, __extention__Q以?span lang="EN-US">gcc内嵌汇编Q还?span lang="EN-US">unsigned long long(直到C99才开始支?span lang="EN-US">)Q如果你使用了其他编译器Q需要修改对应的源程序。且~译器必L32位,q样做的目的是保持源E序z清晰?span lang="EN-US">

对于windows用户可以使用 cygwinQ它提供?span lang="EN-US">windows下的linux环境。不q我没有试使用它,因ؓ我的电脑上没有安?span lang="EN-US">windows操作pȝ。也可以在你?span lang="EN-US">windowspȝ上安装一个虚拟机上的linuxQ如果你的电脑够快的话?span lang="EN-US">


VMWARE

Zq行教程中的范例Q一个虚拟机必不可少Q?span lang="EN-US">virtual pc2007已经可以免费使用了,?span lang="EN-US">M$的官方网站上可以扑ֈ下蝲。当然也可以使用qemu?span lang="EN-US">bochs之类的虚拟机。推荐的虚拟机是VMWARE?span lang="EN-US">

Things Are Good To Know

如果能看?/span>Makefile最好了Q这?/span>*nixE序员必L握的一基本知识。另外,如果你熟悉内存地址映射Q中断,异常Q?/span>GDTQ?/span>LDTQ?/span>IDTQ分|Ӟ范围端口更好了。当然不懂也没关p,Intel的三h册是案头必备Q?/span>http://www.intel.com

IA-32 Intel Architecture Software Developer's Manual Volume1: Basic Architecture
IA-32 Intel Architecture Software Developer's Manual Volume2A: Instruction Set Reference: A-M
IA-32 Intel Architecture Software Developer's Manual Volume2B: Instruction Set Reference: N-Z
IA
-32 Intel Architecture Software Developer's Manual Volume3A: System Programming Guide Part1
IA-32 Intel Architecture Software Developer's Manual Volume3B: System Programming Guide Part2

读者对q些东西不必紧张Q我在教E中会解释相关的知识?span lang="EN-US">c语言和汇~是最基本的要求,能够很清楚的了解什么是堆和栈。关?span lang="EN-US">c语言的数据成千上万,但是保护模式斚w的书c比哈雷慧星q少Q据说每76q可以买C本,如果你够幸q的话:Q?a name="Color_Pattern">

风格U定

 

原文中的格式被擅自去掉了Q翻译后的风格应该可以一看就懂?/span>

 

 



天衣有缝 2007-05-08 07:32 发表评论
]]>
自己动手写内核(序)Q原创)http://www.shnenglu.com/jinglexy/archive/2007/05/08/23595.html天衣有缝天衣有缝Mon, 07 May 2007 23:30:00 GMThttp://www.shnenglu.com/jinglexy/archive/2007/05/08/23595.htmlhttp://www.shnenglu.com/jinglexy/comments/23595.htmlhttp://www.shnenglu.com/jinglexy/archive/2007/05/08/23595.html#Feedback8http://www.shnenglu.com/jinglexy/comments/commentRss/23595.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/23595.html
后来Q我扑ֈ?skelix", 一个os内核Q运行在i386机器上,支持多Q务,分页机制Q虚拟内存,文gpȝ{。这个tutorial教你怎样一步一步实现skelixQ虽然它看v来象一个玩兗这样做的好处是看v来更清晰一些。如果你发现bug或好的徏议可以告诉原作者:xiaoming.mo at skelix dot org。译者:jinglexy at yahoo dot com dot cnQemail and msn bothQ,上v体育馆。预?月䆾译完成Q?007q_Q因q事情比较多,只能偶尔译译Q进度大U?周译1译֐Q也可能快些Q如果有帮忙的就更欢q了。最l整理的文档会做成一个chm或pdf文g发布在http://www.shnenglu.com/jinglex  阅读全文

天衣有缝 2007-05-08 07:30 发表评论
]]>
使用grub中的内核demoQ原创)http://www.shnenglu.com/jinglexy/archive/2007/04/20/22392.html天衣有缝天衣有缝Fri, 20 Apr 2007 09:30:00 GMThttp://www.shnenglu.com/jinglexy/archive/2007/04/20/22392.htmlhttp://www.shnenglu.com/jinglexy/comments/22392.htmlhttp://www.shnenglu.com/jinglexy/archive/2007/04/20/22392.html#Feedback0http://www.shnenglu.com/jinglexy/comments/commentRss/22392.htmlhttp://www.shnenglu.com/jinglexy/services/trackbacks/22392.html
2. 建立testos.lds链接脚本Q?
  阅读全文

天衣有缝 2007-04-20 17:30 发表评论
]]>
使用grub加蝲自己的os及bochs{杂q讎ͼ原创Q?/title><link>http://www.shnenglu.com/jinglexy/archive/2007/04/20/22391.html</link><dc:creator>天衣有缝</dc:creator><author>天衣有缝</author><pubDate>Fri, 20 Apr 2007 09:29:00 GMT</pubDate><guid>http://www.shnenglu.com/jinglexy/archive/2007/04/20/22391.html</guid><wfw:comment>http://www.shnenglu.com/jinglexy/comments/22391.html</wfw:comment><comments>http://www.shnenglu.com/jinglexy/archive/2007/04/20/22391.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/jinglexy/comments/commentRss/22391.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jinglexy/services/trackbacks/22391.html</trackback:ping><description><![CDATA[     摘要: W一节:使用minix盘映象 <br>bochs主页Qhttp://sourceforge.net/projects/bochsQ上有个minix2.0映象Q?<br>~译器和源代码映象文仉已经有了Q如果要mountC自己的机器上~辑源程序, <br>可以使用下面的linux指oQؓ什么是1024?669888Q分析下盘分区表就知道了?<br>Q?024 Q?512 * 2Q?5669888 = 512 * 11074Q?1074?B42Q?<br>/sbin/losetup /dev/loop6 a.img -o 1024 <br>mount -t minix -o loop /dev/loop6 mnt1 <br>ls mnt1  <a href='http://www.shnenglu.com/jinglexy/archive/2007/04/20/22391.html'>阅读全文</a><img src ="http://www.shnenglu.com/jinglexy/aggbug/22391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jinglexy/" target="_blank">天衣有缝</a> 2007-04-20 17:29 <a href="http://www.shnenglu.com/jinglexy/archive/2007/04/20/22391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.csrjgzs.cn" target="_blank">޾ƷŮþþ</a>| <a href="http://www.tmqywedding.cn" target="_blank">þݺҹҹav˳</a>| <a href="http://www.mosphere.cn" target="_blank">ƷþĻ</a>| <a href="http://www.hedv.com.cn" target="_blank">ƷVAþþþþþñ</a>| <a href="http://www.ryjv.cn" target="_blank">˾þþƷ鶹</a>| <a href="http://www.egpk.cn" target="_blank">þ߳ˮ</a>| <a href="http://www.domino111.com.cn" target="_blank">һձ˾þۺӰ</a>| <a href="http://www.68zyw.cn" target="_blank">þоƷƵ</a>| <a href="http://www.84448.com.cn" target="_blank">þþƷһ</a>| <a href="http://www.gd44.cn" target="_blank">91þþþþþ</a>| <a href="http://www.cn1s.cn" target="_blank">þۺĻ</a>| <a href="http://www.sxttzs.cn" target="_blank">seguiþùƷ</a>| <a href="http://www.10jpka.cn" target="_blank">Ӱһþҹײ </a>| <a href="http://www.qkmp4.cn" target="_blank">þþƷɫ鶹</a>| <a href="http://www.gbestech.cn" target="_blank">ҹҹþ</a>| <a href="http://www.u1536.cn" target="_blank">þþƷһ</a>| <a href="http://www.gonnts.cn" target="_blank">þþۺϾɫۺ̾</a>| <a href="http://www.t8s.com.cn" target="_blank">AVһþ</a>| <a href="http://www.veixzew.cn" target="_blank">ľƷ99þù</a>| <a href="http://www.ixlg.cn" target="_blank">þѾƷav</a>| <a href="http://www.9258bbs.cn" target="_blank">ɫۺϾþþþ</a>| <a href="http://www.eboa.com.cn" target="_blank">һɫۺϾþ</a>| <a href="http://www.51peini.cn" target="_blank">þù޾Ʒ</a>| <a href="http://www.port1.com.cn" target="_blank">99þþƷ</a>| <a href="http://www.1704class.cn" target="_blank">vĻþ 뾫ƷþɪӰ </a>| <a href="http://www.lushihu.cn" target="_blank">97Ʒ˾þþô߽97</a>| <a href="http://www.bxzpzlb.cn" target="_blank">66þôýվȸ</a>| <a href="http://www.xbbu.cn" target="_blank">Ʒ99þþƷ</a>| <a href="http://www.68360.cn" target="_blank">Ʒþþþþù</a>| <a href="http://www.liangz.cn" target="_blank">þҹҹ³³ƬӰ</a>| <a href="http://www.vf369.cn" target="_blank">þҹ³˿Ƭ</a>| <a href="http://www.u6768.cn" target="_blank">þþƷ޸</a>| <a href="http://www.7111393.cn" target="_blank">þþƷҹҹҹҹҹþ</a>| <a href="http://www.lafei-pingtai.cn" target="_blank">˾Ʒһþ</a>| <a href="http://www.114tmall.cn" target="_blank">þþþavۺϲҰ</a>| <a href="http://www.zjslzy.com.cn" target="_blank">Ʒþþþþþ</a>| <a href="http://www.bclife.cn" target="_blank">þŮcc98cm</a>| <a href="http://www.ajemy.cn" target="_blank">99ȳ˾ƷѾþ</a>| <a href="http://www.nyvgcd.cn" target="_blank">69Ʒþþþվ</a>| <a href="http://www.ypnlb.cn" target="_blank">yellowĻþ</a>| <a href="http://www.lvomb.cn" target="_blank">þպƷһ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>