多核操作系统实践 实验一.docx
《多核操作系统实践 实验一.docx》由会员分享,可在线阅读,更多相关《多核操作系统实践 实验一.docx(14页珍藏版)》请在冰豆网上搜索。
多核操作系统实践实验一
多核操作系统实践实验一
作者:
卓达城
说明:
由于在linux上打中文太麻烦,虽然本人英文不好,不过还是用英文写,部分地方中文注释。
^^^^^^^^^^^^^^^^^^^^^^^^^PART1^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
首先要做的是安装开发环境。
下载VMware,Ubuntu并安装。
然后下载bochs的源代码,编译安装,编译bochs需要安装几个依赖包。
依赖包包括:
build-essential,xorg-dev,pkg-config,gtk2.0
编译JOS。
编译完之后,修改bochs的配置文件(具体两处),使JOS在bochs中启动。
具体步骤如下:
Firstweneedtoinstallthedevelopmentenvironment.
1.installvmware7.1inwindowsthencreatethevirtualmachineforlinux(ubuntu)
2.installubuntu10.4inthevirtualmachine
3.setthechineseeducationnetworkupdatesourceinubuntu10.4
(设置教育网的linux更新源,不然以现在的网速更新实在令人受不了)
Howtosetit?
google!
4.installbuild-essential:
usingtheubuntusoftwarecentertoinstallthe"build-essential".Youcantypebuild-essentialinthesoftwarecentersearchbar,theninstallthebuild-essential.Becauseofmycomputerissoslowlytoopenthesoftwarecenter,soiuseapt-gettoinstallit.
thecommandis:
sudoapt-getinstallbuild-essential
5.installxorg-dev
thecommandis:
sudoapt-getinstallxorg-dev
6.installpkg-config
thecommandis:
sudoapt-getinstallpkg-config
7.installgtk2.0
thecommandis:
sudoapt-getinstalllibgtk2.0-dev
8.
Downloadthebochsfromourteacher'swebsite.Thenextractittoyourfavouritefolder.
9.
Compilethebochs
Gotothefolderthatyouplacethebochsthen
Typecommand:
./configure--prefix=/usr--enable-disasm--enable-debugger
Iwillinstallbochsinusr.ifinstallinotherfolder,youmayhavetosettheenviromnent.
Typecommand:
make
wait.......
Typecommand:
sudomakeinstall
10.
CompiletheJOS
Downloadthelab1.tar.gzfromourteacher'swebsite
Extractthem.
Ifyouwanttousegmaketypecommand:
ln-s/usr/bin/make/usr/bin/gmake
Ifyouusemakethenyouhavenoneedtodothestepabove
Gotothefolderlab1
typecommand:
make
ortype:
gmake
11.
Editthebochsconfigfile.bochsrc
Thisfileisinthefolderlab1,butitishidden.Youmustcheckedthe"ShowHiddenfiles"(文件是隐藏的,要显示隐藏文件才能看到)
---------------------------------------------------------------------
Openitandfindthestring:
ata0-master:
type=disk,mode=flat,path="./obj/kern/bochs.img",cylinders=100,heads=10,spt=10
Repalceitwith:
ata0-master:
type=disk,mode=flat,path="*******/obj/kern/bochs.img",cylinders=100,heads=10,spt=10
*******isthepathoftheobjfolder'path.
Example:
/home/zdc/labs/lab1/lab1/obj/kern/bochs.img
---------------------------------------------------------------------
Findthestring:
romimage:
file=$BXSHARE/BIOS-bochs-latest,address=0xf0000
Replaceitwith:
romimage:
file=$BXSHARE/BIOS-bochs-latest
12
Runbochs
Thentype2tosetthepathofthe.bochsrc
Ifsuccesstype6
ThenweruntheJOSsuccessfully.
GoodLuck!
!
!
SecondwefinishtheExercise
Exercise1
Learnthex86assemberLanguage
LearntheAT&TassemberLanguage
Exercise2
Familiarwithbochsandbochsdebugger.
Themostusefulcommandsares,c,u/naddress,q,baddress
Exercise3
Understandwhatisthebiosdoing.
Biossetstheidtfirst,initializesthekeydevicesandthenjumpto0000:
7c00
启动的过程:
CPU加电后从地址0xfffffff0开始运行,这个地址指向BIOS的ROM部分。
BIOS先设置中断表,然后检测和初始化关键设备,然后把硬盘的第一个块加载到0x00007c00运行(这里就是我们JOS的boot)。
^^^^^^^^^^^^^^^^^^^^^^^^^PART2^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
第二部分主要是要我们熟悉bochs的调试工作。
Exercise4
Setthebreakpointin0000:
7c00andtraceit.
Wecanusesperformthecommandstepandstep.
Orwecanuseu/naddresstoseeninstructionsstartfromtheaddress
Thedebuggercommandsimples:
b0x0000:
0x7c00
s
u/100x00:
0x7c00
Tracebootmain()linenumber:
100inboot.S
Throughreadtheboot.asm,Wecanknowthatfunctionbootmainwillbecalledin0x0000:
0x7c45(0008:
00007c45).Sowesetthebreakpointin0x0000:
0x7c40,thentypes.Orsetthebreakpointin0x0000:
0x7c45directly.
Tracereadseg()反汇编boot/main.ocommandobjdump-Smain.o-Mintel>main.asm
Throughtracingtheinstructionsperforminbootmain(),wefindthefunctionreadseg()iscalledat0x0000:
0x7d33(0008:
00007d33).
Startat7ce3:
55push%ebp
endat0x7d21
readsect()
Thisfunctioniscalledat[0x00007d0f]0008:
00007d0f,theinstructionis:
call7c81
Startat"7c81:
55push%ebp"
Thisfunctionendat[0x00007ce2]0008:
00007ce2(unk.ctxt):
ret
Afterthisfunction,theesppointto0x7d14
Thenperformserveralinstructionsuntil"7d16:
39fbcmp%edi,%ebx"
Thisinstructionjudgethecondictiontodecidewhethercontinuetojumpto0x7d06,therearesomeinstructionstosettheparametersforreadsectfrom7d06to7d0f
Atexactlywhatpointdoestheprocessortransitionfromexecuting16-bitcodetoexecuting32-bitcode?
movl%cr0,%eax
orl$CR0_PE_ON,%eax
movl%eax,%cr0
[0x00007c2a]0000:
7c2a(unk.ctxt):
movcr0,eax
thisinstructionstarttheprotectmodule
Whatisthelastinstructionofthebootloaderexecuted,andwhatisthefirstinstructionofthekernelitjustloaded?
Thebootloader'slastinstructionis:
[0x00007d84]0008:
00007d84(unk.ctxt):
calleax
Andthefirstinstructionofkernelis:
[0x0010000c]0008:
0010000c(unk.ctxt):
movwordptrds:
0x472,0x1234
Howdoesthebootloaderdecidehowmanysectorsitmustreadinordertofetchtheentirekernelfromdisk?
Wheredoesitfindthisinformation?
Thefunctionreadseg(ph->p_va,ph->p_memsz,ph->p_offset);'ssecondparametertellthebootloaderhowmanysectorsshuoldbeload.
TheSECTSIZEis512defineinthemacro.
Exercise5
FamiliarwithClanguage
Youcandisplayafulllistofthenames,sizes,andlinkaddressesofallthesectionsinthekernelexecutablebytyping:
objdump-h********/lab1/obj/kernel/kernel
notthecommand:
i386-jos-elf-objdump-hobj/kern/kernel
Youcanseetheentrypointbytypethecommand:
objdump-f********/lab1/obj/kernel/kernel
notthecommand:
i386-jos-elf-objdump-fobj/kern/kernel
Wecanseethestartadressis0xf010000c,not0x0010000c,Why?
Exercise6
ThebootloaderloadtheElfto0x10000(fourzero),itinitializethestructsofElf.h.
Whyaretheydifferent?
Becausethebootloadermovethedatato0c00100000(fivezero,ThestructsofElf.hincludethisvalue)usingthecodeinmain.c:
ph=(structProghdr*)((uint8_t*)ELFHDR+ELFHDR->e_phoff);
eph=ph+ELFHDR->e_phnum;
for(;phreadseg(ph->p_va,ph->p_memsz,ph->p_offset);
Thereis
0x00100000:
0x1badb0020x000000030xe4524ffb0x7205c766
0x00100010:
0x340000040x15010f120x0010f0180x000010b8
atthesecondbreakpoint.
Theyareexecutableinstructionsforkernel.
Butwhy0xf0000000==0x00000000
JusttypehelpinourJOS,wewillknowtheture.
_startf010000c(virt)0010000c(phys)(Theloadaddressandthelinkaddress)Whydon'tyoutellmefirst!
!
!
!
!
Exercise7
Ifichangethe"0x7c00"to"0x8c00"inboot/makefrag,thebochswillrunthebiosprogrammetoinitializetheidtandthedevices.
Butwhenfinishedinitialization,thenjumpto0x7c00continuetoruntheinstructions,thebochswillrestartthesimulator.
Why?
Becausethebootloaderisloadat0x8c00.Thereisnoinstructionsat0x7c00.
^^^^^^^^^^^^^^^^^^^^^^^^^PART3^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exercise8
Restartbochs,Weshouldsetthebreakpointin0x0010000c(b0x0010000c),andthentypec.
NowwetypestoseetheJOS'kernelrunstepbystep.
Iamsoluckthatiseetheinstrctionlgdtin[0x00100015]0008:
00100015.
SowecananswertheproblemofExercise8.
After[0x00100015]0008:
00100015thenewmappingtakeseffect.(segmentation,page?
weshouldseethecrregistorstojudgeit).
Openthefileentry.Sthatinthefolderkern.
Wecommentout(注释)theinstruction"lgdtRELOC(mygdtdesc)"using#.
Andthensaveit.
Andthengotothefolderlab1typethecomment:
make
Thenwerunthebochsandsetthebreakpointat0x00100000c
andtypec,thentypes,s,s,.....
Wecanseethat
(0)[0x00100020]0008:
00100020(unk.ctxt):
jmpfar0008:
f0100027;ea270010f00800
8>s
Nextatt=274078546
bx_dbg_read_linear:
physicalmemoryreaderror(phy=0xf0100027,lin=0xf0100027)
9>s
bx_dbg_read_linear:
physicalmemoryreaderror(phy=0xf0100027,lin=0xf0100027)
Why?
Becuasethenewgdtisn'tloadedtothegdtr.
当进入保护模式之后,段寄存器的值都变成索引值通过gdt转换的。
Andthenthe0x0008indexthesegmentdescriptorisn'tthethesegmentdescriptorwereallyneed.
Sothevirtualaddresstophysicaladdresschangeiserror(itchangetotheoldaddress),Sotheresultaboveappear.
Nowwerestoretheentry.S.
AndmaketheJOSagain.
ToseethesourceofJOS'kernel,weneedtoinstallsomesoftwarelikesourceInsight,butinlinuxweusevim+cscopeinsteadofit.
1NowweneedtobuildtheindexinctagslikeSourceInsight.(Theteachersaysthatsourceinsightsimulatethectags,butnowiusectagstosimulatethesourceInsight,haha!
hehe!
:
-))
Gothetherootcatalogueoflab1,andthentypethecommand:
ctags-R
Thentheindexisestablished.Butwewilluseitlater.
Exercise9
Therelationshipamonginprintfmt.c,printf.candconsole.cis:
printfmt->vprintfmt->putch->cputchar->cons-putc->lpt-putc,cga-putc(setthecharcolor)
(printfmt.c..........)(printf.c)(console.c................................)
Thefillinthefunction"vprintfmt"is:
case'o':
//Replacethiswithyourcode.
//putch('X',putdat);
//putch('X',putdat);
//putch('X',putdat);
num=getuint(&ap,lflag);
base=8;
gotonumber;
//break;
Thespecificationofconsole.c
question1:
lpt_putc()usinginI/Oprarallelportpragraming
cag_putc()setthecharandchar'colourthatdisplayonthescreen.15-8bitsaretheattributeofthechar,8-0bitsarethechar'sasciicode.
cons_putc()printthecharonthescreenusethefuntionabove.
cputchar()callthefunctioncons_putc()
cprintf->vcprintf->vprintfmt->putch->cputchar->cons-putc->lpt-putc,cga-putc(setthecharcolor