Thursday, August 9, 2012

Operating Systems

         
JAVA, C++, VB, PHP වැනි විවිධ පරිගණක භාෂා පිළිබද දැනීමක් ඔබට ඇති. නමුත් ඔබ නිර්මාණය කරන වැඩසටහනක් පරිගණකය තුළ ක්‍රියාත්මක වන තත්වයට පත් වන්නේ කෙසේද කියා ඔබ නොදන්නවා විය හැකියි. මෙම දැනුම නොමැතිව පරිගණක වැඩසටහනක් සැලසුම්කරණය, වැඩසටහනක ඇති වැරදි සෙවීම (debug) වැනි පරිගණක වැඩසටහන්කරණයේදි අත්‍යාවශ්‍ය වන කටයුතු සිදු කිරීම අපහසුයි. මෙම ලිපි පෙළෙන් බලාපොරොත්තු වන්නේ පරිගණකයක මෘදුකාංග අංශය ක්‍රියාත්මක වන ආකාරය පිළිබද යම් අවබෝධයක් ලබාදීමයි. පරිගණක වැඩසටහනක ක්‍රියාකාරීත්වය, මෙහෙයුම් පද්ධතියක ක්‍රියාකාරීත්වය, මතුවිය හැකි ගැටලු ආදිය පිළිබද මෙම ලිපි පෙළෙහි ඇතුළත් වෙනවා. මෙහිදී සිදු කරන්නෙ න්‍යායාත්මකව ක්‍රියාවලිය පැහැදලි කිරීමක් බැවින් පරිගණකයක් තුළ මේවා භාවිත වන ආකාරයෙහි යම් වෙනස්කම් පැවතිය හැකියි.
Process එකක ව්‍යුහය 01
අප විසින් සකසනු ලබන program එකක් අවසානයේ පරිගණකය තුළ ක්‍රියාත්මක වන්නේ 1 සහ 0 සමුදායක් ලෙස (machine code) බව ඔබ දන්නවා ඇති. එනම් පරිගණකය හදුනාගන්නේ 1 සහ 0 සදහා වූ වෙනස් වෝල්ටීයතා මට්ටම් දෙකක් පමණයි. එසේ නම් සංකීර්ණ කාර්යයන් සිදුකරන software එකක් මෙලෙස 1 සහ 0 මගින් ක්‍රියාත්මක වන්නේ කෙලෙසද යන ගැටලුව ඔබටත් තිබිය හැකියි. මෙම ලිපි පෙළෙන් එම ක්‍රියාවලිය පිළිබද යම් අවබෝධයක් ලබා දීමට බලාපොරොත්තු වනවා. මෙම ක්‍රියාවලිය පැහැදිලි කිරීමට අවශ්‍ය මූලික දැනුම ලබා දීම සදහා ප්‍රථමයෙන්ම program එකක් run වීමට අදාළ මූලික ක්‍රියාවලිය කෙටියෙන් සළකා බලමු.
ප්‍රථමයෙන්ම hard disk එකේ තියෙන program එක main memory එකට රැගෙන යනවා. program එකක් යනු instruction සමුදායකි. මේ එක් එක් instruction එක processor එක මගින් ක්‍රියාත්මක කිරීම තමයි program එකක් execute කරනව කියල කරන්නෙ.
img1 1
img1 2
main memory එකේ දත්ත ගබඩා කර තැබිය හැකි ස්ථාන වලට memory locations කියල කියනවා. එක් එක් memory location එකට අනන්‍ය වූ address එකක් තියෙනවා. එමගින් අවශ්‍ය memory location එක හදුනාගන්න පුළුවන්. processer(cpu) එක ඇතුලෙ තියෙන program counter(pc) එක මගින් දැන් execute කල යුතු instruction එක තියෙන memory location එකේ memory address එක ගබඩා කරල තියාගන්නවා. මෙම instruction එක cpu එක ඇතුළට ගෙනත් instruction register කියල තැනක තැන්පත් කරනවා. register එකක් කියන්නෙත් memory location එකක් වගේම එකක්. බොහෝ වෙලාවට ඒවා තියෙන්නෙ cpu එක ඇතුලෙ. එම නිසා memory එකට වඩා ගොඩක් වේගවත්. ඉන් පස්සෙ පරිගණකය instruction register එකේ තියෙන instruction එක කියවල ඒක ක්‍රියාත්මක කරනවා. main memory එකේ ඇති දත්තයක් කියවීම main memory එකේ දත්තයක් තැනපත් කිරීම register වල ඇති දත්ත වලින් ගණිතකර්ම සිදු කිරීම වැනි විවිධ instructions මෙලෙස execute කළ හැකියි. එක් instruction එකක් execute කිරීමෙන් පසු ඊලග instruction එක cpu එකේ instruction register එකට ගෙන ආ යුතුයි. ඒ සදහා program counter එකෙහි මීලග instruction එක ඇති memory address එක සටහන් කල යුතුයි. ඉන්පසු පෙර පරිදිම මීලග instruction එක execute කල යුතුයි

Operating systems


02
අප ‍විසින් සකස් කරන program එකක් අවසන් වශයෙන් පරිගණකය තුළ execute වී‍ම සිදුවන ආකාරය පැහැදිලි කරන්නට මෙම ලිපියෙන් බලාපොරොත්තු වෙනවා. මේකෙදි කතා කරන්නෙ execute වී‍මට අවශ්‍ය මූලිකම ‍දේවල් ටිකක් ගැන විතරයි.
අපි program එකක් සකස් කළ විට ඒක ගොඩක් සංවිධානාත්මකව තියෙනවා. ඒක බලපු ගමන් අපට එයින් සිදුවන දේ පැහැදිලිව තේරුම් ගන්න පුළුවන්. නමුත් පරිගණකය‍ට ඒ දේ කරන්න බැහැ. එයට එකින් එක සිදු කල යුතු සියලුම දේවල් කියන්න ඕනි. මේ අපි තේරුම් ගත යුතු වැදගත්ම දෙයක්. කල යුතු ඉතාමත් සුළු පිය‍වරක් උනත් ප‍රිගණකය‍ට අපි විසින් කියන්න ඕනි. මේක මෙහෙම කියද්දි ‍හොදට දන්න දෙයක් කියල හිතුනත් ඒක එච්චර ලේසියෙන් තේරුම් යන්නෙ නෑ. ඒ ගැන හොදින් හිතල බලන්න. ඒත් ඔබ code එකක් ලියද්දි මේ හැම පියවරක්ම ලියන්නෙ නෑනෙ. ඒත් ඔබ code එක compile කලාම compiler එක ඔබ වෙනුවෙන් ඒ දේවල් සිදු කරල දෙනවා. Assembly code එකක් ලියද්දි ඔබ මේ කරුණ ගැන හරියටම තේරුම් අරගෙන තියෙන්න ඕනි. මොකද assembly code එකක් කියන්නෙ compile කලාට පස්සෙ ලැබෙන එකක්.
අපි සරල code එකක් භාවිතා කරල මේ ක්‍රියාවලිය පැහැදිලි කර ගනිමු.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {
 
 int a = 10;
 int b = 5;
 int c = add(a,b);
 return 0;
 
}
 
int add(int x, int y) {
 
 int z = x+y;
 return z;
 
}

ඉහත code එක compile කලාම කලින් කිව්ව විදියට compiler එක ඔබ වෙනුවෙන් අවශ්‍ය එකතු කිරීම් කරල RAM එක තුළ එක් එක් instruction එක තැබිය යුතු memory address දක්වාම වූ සියලු විස්තර file එකකට ලියනවා. එම program එක run වෙද්දි RAM එක තුළ දත්ත පහත විදියට විහිදෙනවා කියල හිතමු.
img2 1
assembly code ලිවීමේ දී සලකන විවිධ segment භාවිත කරන ක්‍රියාවලිය මදකට අමතක කරන්න. මේකෙ පැහැදිලි කරන්නෙ එක් method එකකට අදාල දත්ත එක තැනක තියෙනව කියල සලකලයි.
ඉහත පින්තූරයේ තියෙන විදියට memory address 1000-1050 වන තුරු main method එකත් 1100-1120 වන තුරු add method එකත් තියෙනව කියල හිතමු. Code එක compile කරන කොටම මොන memory address වලද program එක ලියවෙන්න ඕනි කියන එක file එකේ ලියවෙනවා. මොකද jump statement එකක් එහෙම තිබ්බොත් යන්න ඕනි මොන memory address එකටද කියන එක program එක දැනන් ඉන්න ඕනි. Code එක compile කරද්දිම memory address ලියවෙනවා නම් ප්‍රශ්නයක් තියෙනවා. Program එක compile කරන්නෙ එක වෙලාවක ඒත් ඊට පස්සෙ විවිධ වෙලා වලදි ඒක run කරනව. නමුත් ඒ හැම වෙලාවකදිම එකම memory එකේ ස්ථාන හිස්ව තියෙනවා කියල කියන්න බැහැ. මොකද එකම වෙලාවෙ program කිහිපයක් ‍වැඩ කරන්න පුළුවන්නෙ. නමුත් අපි දැනට සලකමු අපේ program එකට මුළු memory එකම භාවිත කරන්න පුළුවන් කියල. එහෙම උනොත් ඉහත code එකේ ගැටලුවක් එ‍න්නෙ නෑ. ඒත් ඉහත code එකේ main method එකත් add method එකත් ‍ file දෙකක ලියල තියෙනව නම් ඒ file දෙක වෙන වෙනම compile කරන්න පුළුවන්නෙ. එතකොට....????
එතකොට එක් file එකක් අනිත් file එක භාවිත කරන memory address පිළිබද අව‍බෝධයක් නැහැ. File දෙකම එකම memory address භාවිත කරන්න ඉඩ තියෙනවා. එවිට එම program එක run වෙන්න විදියක් නැහැ. මෙම තත්වය මග හරවා ගන්නෙ linker එක භාවිතයෙන්.
main.c
1
2
3
4
5
6
7
8
int main() {
 
 int a = 10;
 int b = 5;
 int c = add(a,b);
 return 0;
 
}

add.c
1
2
3
4
5
6
int add(int x, int y) {
 
 int z = x+y;
 return z;
 
}
img2 2
main method එක main.c file එකෙත් add method එක add.c file එකෙත් තියෙනව කියල හිතමු. compiler එකෙන් මේ file දෙක main.o add.o කියල file දෙකකට වෙන වෙනම compile කරනව කියල හිතමු. linker එකෙන් කරන්නෙ මේ file දෙකේ තියෙන දත්ත තනි file එකකට අලුතෙන් ලියන එක. එහෙම ලියද්දි memory address වල ගැටලුවක් වෙන්නෙ නැති විදියට memory එකේ තැන් දෙකකට එන විදියටයි ඒක ලියන්නෙ.
img2 3