<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Łukasz Sowa</title>
	<atom:link href="http://lukaszsowa.pl/feed/" rel="self" type="application/rss+xml" />
	<link>http://lukaszsowa.pl</link>
	<description>O programowaniu i nie tylko ;)</description>
	<lastBuildDate>Mon, 06 Feb 2012 12:09:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Jak (wg mnie) uczyć się na studiach?</title>
		<link>http://lukaszsowa.pl/2011/09/jak-wg-mnie-uczyc-sie-na-studiach/</link>
		<comments>http://lukaszsowa.pl/2011/09/jak-wg-mnie-uczyc-sie-na-studiach/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 14:56:34 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Prywata]]></category>
		<category><![CDATA[Różne]]></category>
		<category><![CDATA[elka]]></category>
		<category><![CDATA[studia]]></category>
		<category><![CDATA[życie]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=645</guid>
		<description><![CDATA[Sześć semestrów studiowania już za mną &#8211; to znaczy, że jestem już za połową. Dużo kolokwiów i egzaminów udało mi się już zaliczyć, zarywając przy tym jeszcze więcej nocy. To wszystko znaczy, że pewne doświadczenie w studiowaniu już mam i wydaje mi się, że już niewiele rzeczy jest w stanie mnie na studiach zaskoczyć ;). [...]]]></description>
			<content:encoded><![CDATA[<p>Sześć semestrów studiowania już za mną &#8211; to znaczy, że jestem już za połową. Dużo kolokwiów i egzaminów udało mi się już zaliczyć, zarywając przy tym jeszcze więcej nocy. To wszystko znaczy, że pewne doświadczenie w studiowaniu już mam i wydaje mi się, że już niewiele rzeczy jest w stanie mnie na studiach zaskoczyć ;). Wiem, że zagląda tu sporo studenckiej braci, dlatego postanowiłem dać kilka porad młodszym rangą od siebie :).</p>
<h2>Semestry początkowe, czyli kurowa wszystkich nauk</h2>
<p>Na chyba każdej uczelni technicznej pierwsze semestry składają się głównie z matematyki. Algebra, analiza, logika, statystyka &#8211; to standard. Semestry te są też podobno najtrudniejsze i na nich odpada najwięcej osób. Na mojej kochanej Uczelni z matematyki dawano nieobowiązkowe zestawy zadań, które później robione były na ćwiczeniach. Jak się okazało, najskuteczniejszym podejściem do sprawy było po prostu robienie ich samodzielnie wcześniej. Owszem, zabierało to dużo czasu: dzień przed ćwiczeniami widywałem wschody słońca, przy piwku i zeszycie z całeczkami; owszem było to nudne, a czasem wręcz niesamowicie irytowało; ale owszem &#8211; dawało to wybitne wyniki: dzień przed kolokwium wystarczyło przejrzeć wykonaną wcześniej pracę, a samo kolokwium wydawało się dziecinnie proste. Do matematyki podejście jest więc proste: ćwiczyć, ćwiczyć i jeszcze raz klepać schematy &#8211; a zaliczenie przyjdzie bez problemu.</p>
<p>Warto jeszcze wspomnieć dwa słowa o wykładach i ćwiczeniach. Na wykładach bardzo często dyktowana jest książka (z dokładnością do takich samych przykładów). Można więc pokusić się o absencje, jednak wtedy trzeba taką książkę załatwić, albo wziąć od kogoś notatki. Ja mimo wszystko uczęszczałem na wykłady, głównie dlatego że najmilej czyta mi się swoje własne pismo i żartobliwe rysunki :P. Co do ćwiczeń, to warto chodzić &#8211; głównie po to, żeby zweryfikować swoje rozwiązania i załapać punkty za aktywność.</p>
<h2>Semestry dalsze, czyli pozostałe dobrodziejstwa inwentarza</h2>
<p>Pozostałe przedmioty na studiach (pamiętajmy, że ciągle mówimy o informatyce) można podzielić na takie, które wymagają wiedzy (np. architektura komputerów, systemy operacyjne, grafika komputerowa) i takie które wymagają klepania schematów (np. teoria obwodów, teoria informacji, automatyka, optymalizacja). Co do drugiej (gorszej, nota bene) kategorii strategia jest taka sama jak dla matematyki &#8211; trzeba się po prostu tych schematów nauczyć, a później na kolokwium/egzaminie wyklepać. Tutaj niebywale przydaje się bank kolokwiów i egzaminów z ostatnich lat do poćwiczenia. Poza tym, nie trzeba chyba wspominać, że wiele zadań się po prostu powtarza :). Nauka schematów jest żmudna, ale nie jest trudna, dlatego też chodzenie na wykłady z przedmiotów &#8222;schematycznych&#8221; jest raczej zbędne &#8211; chyba że ktoś naprawdę lubi patrzeć jak się oblicza kolejną całkę na tablicy.</p>
<p>Dosyć już jednak narzekania, przejdźmy do przedmiotów wymagających wiedzy, czyli bardziej złożonej materii. W trakcie 6 semestrów nauki udało mi się wypróbować dwie strategie &#8211; opiszę więc każdą z nich.</p>
<h3>Noc przed, zasada indukcji, od zera do bohatera</h3>
<p>Strategia ta jest bardzo prosta. Zakłada ona, że da się wszystkiego nauczyć na egzamin/kolokwium w nocy przed takowym. Zwykle nie ma wtedy mowy o spaniu, trzeba mieć dużo samozaparcia i wytrwale siedzieć i czytać. Strategia ta działa i jest praktykowana przez wiele osób &#8211; z sukcesami. Ma ona jeden szkopuł &#8211; niestety trzeba mieć pewną, podstawową wiedzę wyniesioną z wykładów (albo z książek, tudzież doświadczenia). Dla przykładu uczenie się algorytmów &#8222;od zera&#8221; w 8 godzin jest zbyt męczące psychicznie = niemożliwe. Z drugiej strony, mi z podstawami sztucznej inteligencji się udało &#8211; z zerową wiedzą wyniesioną z wykładu ;). Skuteczność tej metody zależy więc od materii i osobistych predyspozycji.</p>
<p>Zastanówmy się teraz nad czymś takim: &#8222;a co jeśli jednego dnia mam n kolokwiów?&#8221; (n &gt; 1). Słynna zasada indukcji studenta mówi, że jeśli student jest w stanie nauczyć się do n kolokwiów w nocy przed, to jest też w stanie nauczyć się do n+1 kolokwiów. Dlatego jeśli jesteś w stanie przygotować się do kolosa na noc przed, to z dwoma, trzema&#8230; też nie będziesz miał problemów :). Tutaj jednak warto wiedzieć o <a href="http://pl.wikipedia.org/wiki/Zasada_Pareto">zasadzie Pareto</a>. Noc może nie starczyć, aby nauczyć się na 100%, jednak pewien (poniekąd 20%) wkład w każdy z n podproblemów da nam wysoki (poniekad 80%) wynik.</p>
<p>Co natomiast robić, jeśli na wykładach nie pojawialiśmy się w ogóle, a kolokwium/egzamin zbliża się nieubłaganie? Cóż, innego wyjścia nie ma, jak tylko kuć wytrwale nie przez jedną, a np. przez trzy kolejne noce. &#8222;Od zera do bohatera&#8221; w 3 dni wydaje się być osiągalne, niezależnie od poziomu skomplikowania materii. Może to być jednak wyjątkowo wyczerpujące i niemiłe. Spróbowałem raz &#8211; udało się, ale rzeczywiście było niemiło.</p>
<h3>Systematyczność</h3>
<p>Systematyczność &#8211; tego słowa nienawidzą wszyscy uczniowe. Nauczyciele nieustannie, od lat powtarzają &#8211; ucz się systematycznie, a wyniki przyjdą same. Po 5 semestrach wykorzystywania zasady &#8222;noc przed&#8221;, na 6 semestrze postanowiłem spróbować (eksperymentalnie) uczyć się systematycznie <strong>każdego</strong> przedmiotu. Nie ze wszystkimi się udało, bo niektóre były zbyt ohydne, ale jednak z większością tak :). Efekty? Znakomite. Wyniki oscylujące w okolicy 100% były normą. Koszt? Ogromny. Wymagało to wytrwałego chodzenia na wykłady i codziennej powtórki (około dwugodzinnej) tego, co udało mi się tam nauczyć. Dostrzegłem też pewien pozytywny efekt uboczny: w końcu czułem, że do przedmiotów, które lubie przykładam się w stopniu zadawalającym.</p>
<h2>Aurea mediocritas</h2>
<p>&#8222;Jak więc żyć, drogi Łukaszu?&#8221; słyszę pytania z tłumu. Już stoicy znali na nie odpowiedź: <strong>złoty środek</strong>. Dla przedmiotów ze schematami należy uczyć się schematów &#8211; najlepiej tak, aby mechanicznie je odtwarzać, gdy ktoś o nie pyta. Dla nudnych, nieciekawych przedmiotów wymagających wiedzy warto stosować taktykę &#8222;olewczą&#8221;, czyli uczyć się na noc przed. Do przedmiotów interesujących i lubianych najlepiej uczyć się systematycznie.</p>
<p>W ten sposób pielęgnujemy swoje pasje i zainteresowania i zaliczamy kolejne przedmioty, utrzymując przy tym stan frustracji na rozsądnym poziomie.</p>
<h2>Disclaimer</h2>
<p>Przedstawione powyżej metody działały dla mnie znakomicie. Nie tylko pozwalały gładko zaliczać kolejne przedmioty, ale również dawały dobre wyniki (jeśli mierzyć je wysokością oceny). Warto jednak pamiętać, że nie każdy ma taki sam styl nauki. Niektórzy nie są wstanie przesiedzieć nocy nad książką, innym wystarczy tylko chwilowe spojrzenie na coś i już to potrafią. Do tego, moje doświadczenia opieram wyłącznie na moich studiach, które mogą być specyficzne, ze względu na kierunek czy wydział/uczelnię. Należy więc wypracować indywidualny tryb pracy, a powyższe metody potraktować jako pewną możliwość. Sukcesu więc nie gwarantuję, jednak z całego serca życzę :).</p>
<div id="-chrome-auto-translate-plugin-dialog" style="opacity: 1 !important; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: transparent !important; position: absolute !important; top: 0px; left: 0px; overflow-x: visible !important; overflow-y: visible !important; z-index: 999999 !important; text-align: left !important; display: none; background-position: initial initial !important; background-repeat: initial initial !important; padding: 0px !important; margin: 0px !important;">
<div style="max-width: 300px !important; color: #fafafa !important; opacity: 0.8 !important; border-color: #000000 !important; border-width: 0px !important; -webkit-border-radius: 10px !important; background-color: #363636 !important; font-size: 16px !important; padding: 8px !important; overflow: visible !important; background-image: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #000), color-stop(50%, #363636), color-stop(100%, #000)); z-index: 999999 !important; text-align: left  !important;"></div>
<p><img style="position: absolute !important; z-index: -1 !important; right: 1px !important; top: -20px !important; cursor: pointer !important; -webkit-border-radius: 20px; background-color: rgba(200, 200, 200, 0.3) !important; padding: 3px 5px 0 !important; margin: 0 !important;" onclick="document.location.href='http://translate.google.com/';" src="http://www.google.com/uds/css/small-logo.png" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2011/09/jak-wg-mnie-uczyc-sie-na-studiach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tworzenie systemu operacyjnego – część 0×06: Porządki, GDT, VGA&#8230;</title>
		<link>http://lukaszsowa.pl/2011/07/tworzenie-systemu-operacyjnego-%e2%80%93-czesc-0%c3%9706-porzadki-gdt-vga/</link>
		<comments>http://lukaszsowa.pl/2011/07/tworzenie-systemu-operacyjnego-%e2%80%93-czesc-0%c3%9706-porzadki-gdt-vga/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 18:10:31 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[osdev]]></category>
		<category><![CDATA[systemy operacyjne]]></category>
		<category><![CDATA[tworzenie systemu operacyjnego]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=634</guid>
		<description><![CDATA[W szóstej odsłonie serii zajmę się małymi porządkami, które zaprocentują w najbliższej przyszłości. Przede wszystkim uporządkuję kilka spraw, wrócę raz jeszcze do GDT oraz napiszę kilka funkcji, które będą pomocne przy wypisywanu komunikatów diagnostycznych, których nigdy za wiele ;). Raczkująca przenośność Twórcy niektórych systemów operacyjnych stawiają sobie za zadanie dotarcie do możliwe (potencjalnie!) najszerszej rzeszy [...]]]></description>
			<content:encoded><![CDATA[<p>W szóstej odsłonie serii zajmę się małymi porządkami, które zaprocentują w najbliższej przyszłości. Przede wszystkim uporządkuję kilka spraw, wrócę raz jeszcze do <a href="http://lukaszsowa.pl/gdt/">GDT</a> oraz napiszę kilka funkcji, które będą pomocne przy wypisywanu komunikatów diagnostycznych, których nigdy za wiele ;).</p>
<h2>Raczkująca przenośność</h2>
<p>Twórcy niektórych systemów operacyjnych stawiają sobie za zadanie dotarcie do możliwe (potencjalnie!) najszerszej rzeszy użytkowników. Tworzą oni implementacje dla różnych architektur procesorów i starają się, aby dodanie kolejnych było w miarę łatwe. Inni całkowicie na to leją, gdyż biznesowo patrząc &#8211; jest to nieopłacalne. Przykłady jednych i drugich łatwo wymyślić, więc nie będę ich tu podawał ;). W swoim systemie postanowiłem zrobić kroczek w stronę stworzenia przenośnego systemu operacyjnego &#8211; maksymalnie wykorzystuję język C, który jest przenośny (od mikrokontrolerów aż do dużych, &#8222;poważnych&#8221; procesorów), a minimalizuję użycie assemblera, który tej cechy nie posiada.</p>
<h3>Magia typedef</h3>
<p>Każdy, kto programował trochę w C i C++ wie jak bardzo przydatnym i potężnym narzędziem jest słowo kluczowe <em>typedef</em>. Każdy znany mi system operacyjny często i gęsto wykorzstuje &#8222;<em>typedefowanie</em>&#8221; &#8211; mam więc i ja :).</p>
<p>Wielokrotnie podczas tworzenia oprogramowania poziomu jądra potrzebne są nam typy, które posiadają ściśle określoną liczbę bitów &#8211; 8, 16, 32 itd. Typy o ustalonej długości służą do tworzenia flag, pól bitowych itp. Niestety specyfika architektur i co gorsza &#8211; kompilatorów powoduje, iż dany typ (int, short, long) ma często nieznaną z góry bitową długość. Można sobie jednak z tym poradzić tworząc odpowiednie definicje typów jak np. moje:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> u32int<span style="color: #339933;">;</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">signed</span> <span style="color: #993333;">int</span> s32int<span style="color: #339933;">;</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">short</span> u16int<span style="color: #339933;">;</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">signed</span> <span style="color: #993333;">short</span> s16int<span style="color: #339933;">;</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> u8int<span style="color: #339933;">;</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">signed</span> <span style="color: #993333;">char</span> s8int<span style="color: #339933;">;</span></pre></div></div>

<p>Dzięki temu, dla każdej architektury można stworzyć taki plik i podczas kompilacji włączać odpowiedni. Takie podejście ma jeszcze jedną zaletę &#8211; nazwa s8int (s od signed, 8 od liczby bitów i int od typu całkowitoliczbowego) jest bardziej wymowna niż char :). To pierwszy, malutki krok ku przenośności &#8211; wymaga on jednak konsekwencji w stosowaniu.</p>
<h3>Opakowanie</h3>
<p>W języku C nie da się zaprogramować wszystkiego &#8211; czasem trzeba skorzystać z instrukcji assemblera specyficznych dla danej architektury. Bywa jednak, że pewna instrukcja występuje na niemal każdej architekturze, jednak pod inną postacią. Warto wtedy opakować taką instrukcję w odpowiednią funkcję w języku C. Przykładem takiej instrukcji jest instrukcja zatrzymująca prace procesora &#8211; dla x86 jest to instrukcja <em>hlt</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">inline</span> <span style="color: #993333;">void</span> hlt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	asm <span style="color: #993333;">volatile</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;hlt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Opakowanie jak widać jest banalne, a może w przyszłości oszczędzić wiele kłopotów. Co więcej, możemy ją teraz swobodnie wykorzystywać w wielu miejscach w kodzie w C!</p>
<p>Warto jeszcze zauważyć, że używam składni tzw. inline assembly, która dla GCC jest bardzo specyficzna (czyt. paskudna). Jest jednak o tym dużo <a href="http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.htmlhttp://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html">artykułów</a>, więc ja się rozpisywać nie będę.</p>
<h2>GDT &#8211; znowu&#8230;</h2>
<p>Jakiś czas temu <a href="http://lukaszsowa.pl/2010/11/tworzenie-systemu-operacyjnego-%E2%80%93-czesc-0%C3%9705-multiboot-specification/">pisałem o multiboot</a>, który ustawia odpowiednio tablicę GDT. Wszystko byłoby pięknie &#8211; jest jednak pewien problem &#8211; nie wiemy dokładnie gdzie znajduje się ta tablica, nie wiemy również, co tak naprawdę się tam znajduje. Warto więc ustawić ją jeszcze raz &#8211; po swojemu i w znanym miejscu, a do tego &#8211; używając głównie C. Na początek struktura deskryptora:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> gdt_descr
<span style="color: #009900;">&#123;</span>
	u16int limit_low<span style="color: #339933;">;</span>
	u16int base_low<span style="color: #339933;">;</span>
	u8int base_middle<span style="color: #339933;">;</span>
	u8int access<span style="color: #339933;">;</span>
	u8int granularity<span style="color: #339933;">;</span>
	u8int base_high<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> __attribute__<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>packed<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> gdt_descr_t<span style="color: #339933;">;</span></pre></div></div>

<p>oraz wskaźnika na samą tablicę:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> gdt_ptr
<span style="color: #009900;">&#123;</span>
	u16int limit<span style="color: #339933;">;</span>
	u32int base<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> __attribute__<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>packed<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> gdt_ptr_t<span style="color: #339933;">;</span></pre></div></div>

<p>W obu przypadkach używam atrybutu <em>packed</em>, który instruuje kompilator, aby nie stosował wyrównania naturalnego dla architektury (to pewien rozdzaj optymalizacji) &#8211; tylko aby bajty były ciasno upakowane koło siebie ;). Struktura powyższych typów powinna być jasna. Została ona szeroko omówiona w <a href="http://lukaszsowa.pl/gdt/">poprzenich częściach</a> <a href="http://lukaszsowa.pl/2010/10/tworzenie-systemu-operacyjnego-%E2%80%93-czesc-0%C3%9703-przejscie-do-trybu-chronionego/">kursu</a>. Pozostałe kwestie są już trywialne, na początek deklaracja tablicy i wskaźnika na nią:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define GDT_LEN 5</span>
&nbsp;
<span style="color: #993333;">static</span> gdt_descr_t gdt<span style="color: #009900;">&#91;</span>GDT_LEN<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">static</span> gdt_ptr_t gdt_ptr<span style="color: #339933;">;</span></pre></div></div>

<p>funkcja ustawiająca pojedynczy deskryptor:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #993333;">void</span> gdt_set_desc<span style="color: #009900;">&#40;</span>gdt_descr_t<span style="color: #339933;">*</span> descr<span style="color: #339933;">,</span> u32int base<span style="color: #339933;">,</span> u32int limit<span style="color: #339933;">,</span> u8int access<span style="color: #339933;">,</span> u8int granularity<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        descr<span style="color: #339933;">-&gt;</span>base_low <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>base <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xFFFF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        descr<span style="color: #339933;">-&gt;</span>base_middle <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>base <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">16</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
        descr<span style="color: #339933;">-&gt;</span>base_high <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>base <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">24</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xFF</span><span style="color: #339933;">;</span>
        descr<span style="color: #339933;">-&gt;</span>limit_low <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>limit <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xFFFF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        descr<span style="color: #339933;">-&gt;</span>granularity <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>limit <span style="color: #339933;">&gt;&gt;</span> <span style="color: #0000dd;">16</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x0F</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span>granularity <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0xF0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        descr<span style="color: #339933;">-&gt;</span>access <span style="color: #339933;">=</span> access<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>oraz funkcja ustawiająca poszczególne deskryptory:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> gdt_init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        gdt_set_desc<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>gdt<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                <span style="color: #666666; font-style: italic;">// null</span>
        gdt_set_desc<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>gdt<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xFFFFFFFF</span><span style="color: #339933;">,</span> <span style="color: #208080;">0x9A</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xCF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ring0 code</span>
        gdt_set_desc<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>gdt<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xFFFFFFFF</span><span style="color: #339933;">,</span> <span style="color: #208080;">0x92</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xCF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ring0 data</span>
        gdt_set_desc<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>gdt<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xFFFFFFFF</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xFA</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xCF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ring3 code</span>
        gdt_set_desc<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>gdt<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xFFFFFFFF</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xF2</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xCF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ring3 data</span>
&nbsp;
        gdt_ptr.<span style="color: #202020;">base</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>u32int<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>gdt<span style="color: #339933;">;</span>
        gdt_ptr.<span style="color: #202020;">limit</span> <span style="color: #339933;">=</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>gdt_descr_t<span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> GDT_LEN <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
        gdt_set<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>gdt_ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Warto zauważyć, że tym razem tworzymy dokładnie 5 deskryptorów. Pierwszy z nich to tradycyjnie deskryptor NULL, następnie mamy deskryptory kodu i danych dla przestrzeni jądra oraz deskryptory kodu i danych dla przestrzeni użytkownika. Wszystkie, oprócz NULL, rozciągają się oczywiście na całe 4GiB pamięci &#8211; różnią się tylko typem i <a href="http://lukaszsowa.pl/2010/10/ogolna-koncepcja-ochrony-w-x86/">prawami dostępu</a>. Pozostała już tylko funkcja ustawiająca nową tablicę GDT, czyli <em>gdt_set()</em>, niestety tym razem należy skorzystać z kodu assemblera:</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #009900; font-weight: bold;">&#91;</span>GLOBAL gdt_set<span style="color: #009900; font-weight: bold;">&#93;</span>
&nbsp;
gdt_set<span style="color: #339933;">:</span>
        <span style="color: #00007f; font-weight: bold;">mov</span>     <span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">esp</span><span style="color: #339933;">+</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#93;</span>    <span style="color: #666666; font-style: italic;">; get passed pointer</span>
        <span style="color: #00007f; font-weight: bold;">lgdt</span>    <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #00007f;">eax</span><span style="color: #009900; font-weight: bold;">&#93;</span>           <span style="color: #666666; font-style: italic;">; load new GDT pointer</span>
&nbsp;
        <span style="color: #00007f; font-weight: bold;">mov</span>     <span style="color: #00007f;">ax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">0x10</span>        <span style="color: #666666; font-style: italic;">; load all data segment registers</span>
        <span style="color: #00007f; font-weight: bold;">mov</span>     <span style="color: #00007f;">ds</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
        <span style="color: #00007f; font-weight: bold;">mov</span>     <span style="color: #00007f;">es</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
        <span style="color: #00007f; font-weight: bold;">mov</span>     <span style="color: #00007f;">fs</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
        <span style="color: #00007f; font-weight: bold;">mov</span>     <span style="color: #00007f;">gs</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
        <span style="color: #00007f; font-weight: bold;">mov</span>     <span style="color: #00007f;">ss</span><span style="color: #339933;">,</span> <span style="color: #00007f;">ax</span>
        <span style="color: #00007f; font-weight: bold;">jmp</span>     <span style="color: #0000ff;">0x08</span><span style="color: #339933;">:.</span>flush     <span style="color: #666666; font-style: italic;">; far jump to code segment</span>
<span style="color: #339933;">.</span>flush<span style="color: #339933;">:</span>
        <span style="color: #00007f; font-weight: bold;">ret</span></pre></div></div>

<p>kod ten jest jednak bardzo prosty i powinien być bez problemu zrozumiały.</p>
<h2>VGA</h2>
<p>Najstarsza metoda debuggowania programów (podobno odnaleziono ją na ścianach jaskini Lascaux) polega na wypisywaniu otrzymywanych wartości i &#8222;ręcznej&#8221; ich analizie. Niestety, w przestrzeni jądra jest to często <strong>jedyna</strong> dostępna możliwość. Warto więc zadbać o taką możliwość od samego początku. W swoim systemie (przynajmniej na razie) wykorzystuję podstawowe możliwości kart zgodnych z <a href="http://wiki.osdev.org/Category:VGA">VGA</a>, tak jak robiłem to już wcześniej. Funkcja inicjująca wykrywa typ monitora i ustawia odpowiedni adres pamięci zamapowanej na pamięć VGA. Przy wykrywaniu korzystam z pomocnych informacji, które <a href="http://wiki.osdev.org/Detecting_Colour_and_Monochrome_Monitors">pozostawił BIOS</a>. Ustawiam też wirtualną pozycję kursora:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define SCREEN_HEIGHT 25</span>
<span style="color: #339933;">#define SCREEN_WIDTH 80</span>
&nbsp;
<span style="color: #993333;">static</span> u16int<span style="color: #339933;">*</span> vga_mem<span style="color: #339933;">;</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">int</span> cursor<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">void</span> vga_init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        cursor <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">volatile</span> u16int<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #208080;">0x410</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x30</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #208080;">0x30</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// detecting monochrome monitor</span>
                vga_mem <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>u16int<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #208080;">0xB0000</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">else</span>
                vga_mem <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>u16int<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #208080;">0xB8000</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// it's color</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Powyżej widać też definicje wysokości i szerokości typowego monitora VGA, czyli 80&#215;25 znaków.</p>
<p>Pierwszą &#8222;piszącą&#8221; funkcją jest funkcja czyszcząca ekran:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> vga_cls<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> SCREEN_WIDTH <span style="color: #339933;">*</span> SCREEN_HEIGHT<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
                <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span>vga_mem <span style="color: #339933;">+</span> i<span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>u16int<span style="color: #009900;">&#41;</span> <span style="color: #0000dd;">3872</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ((((0 &lt;&lt; 4) | (15 &amp; 0xFF)) &lt;&lt; 8) | 0x20) // white spaces on black background</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Jak widać, po prostu piszę 80*25 spacji na czarnym tle ;). Jeśli sposób pisania po ekranie nadal jest niejasny, to proponuję spojrzeć na <a href="http://lukaszsowa.pl/2010/10/tworzenie-systemu-operacyjnego-%E2%80%93-czesc-0%C3%9704-kernel-w-c/">ten wpis</a>.</p>
<p>Najważniejszą funkcją, jest jednak funkcja produkująca napisy na ekranie. Jest ona dosyć skomplikowana, gdyż sterownik VGA nie potrafi wypisywać znaków nowej linii \n, tabulacji \t oraz powrotu karetki \r &#8211; są one obsługiwane oddzielnie:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> vga_puts<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> str<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// white letters on black background</span>
	<span style="color: #993333;">const</span> u16int attribute <span style="color: #339933;">=</span> <span style="color: #0000dd;">3840</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ((((0 &lt;&lt; 4) | (15 &amp; 0x0F)) &lt;&lt; 8))</span>
&nbsp;
	<span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>cursor <span style="color: #339933;">==</span> SCREEN_WIDTH <span style="color: #339933;">*</span> SCREEN_HEIGHT<span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			vga_scroll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			cursor <span style="color: #339933;">=</span> SCREEN_WIDTH <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>SCREEN_HEIGHT <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #339933;">:</span>
			cursor <span style="color: #339933;">=</span> cursor <span style="color: #339933;">+</span> <span style="color: #0000dd;">80</span> <span style="color: #339933;">-</span> cursor <span style="color: #339933;">%</span> <span style="color: #0000dd;">80</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\r</span>'</span><span style="color: #339933;">:</span>
			cursor <span style="color: #339933;">=</span> cursor <span style="color: #339933;">-</span> cursor <span style="color: #339933;">%</span> <span style="color: #0000dd;">80</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\t</span>'</span><span style="color: #339933;">:</span>
			<span style="color: #666666; font-style: italic;">// increment to align to 8</span>
			<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>cursor <span style="color: #339933;">%</span> <span style="color: #0000dd;">80</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">%</span> <span style="color: #0000dd;">8</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
				<span style="color: #339933;">++</span>cursor<span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">default</span><span style="color: #339933;">:</span>
			vga_mem<span style="color: #009900;">&#91;</span>cursor<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>u16int<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span>attribute <span style="color: #339933;">|</span> str<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #339933;">++</span>cursor<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #339933;">++</span>i<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>W przypadku typowego znaku po prostu wpisuję odpowiednią wartość do pamięci pod adresem vga_mem[cursor] i inkrementuję pozycję kursora. Dla \n dodaję 80 (długość linii) a następnie odejmuję tyle, aby powstała liczba była podzielna bez reszty przez 80 &#8211; czyli po prostu przechodzę do kolejnej linii. Dla \r robię operację podobną &#8211; tyle, że nie dodaję 80, co powinno być oczywiste. Dla \t dodaję do pozycji kursora 1 dopóki pozycja w aktualnym wierszu jest niepodzielna przez 8 (typowe zachowanie tabulacji w systemach UNIX).  Na początku funkcji widać jeszcze obsługę sytuacji, gdy zapełnimy cały ekran znakami &#8211; przenoszę wtedy nasz wirtualny kursor na początek ostatniej linijki i wywołuję wtedy <em>scroll()</em>, która przepisuje wiersze &#8222;o jeden do góry ekranu&#8221; &#8211; pierwszy wiersz zostaje nadpisany drugim itd., ostatni wiersz zostaje wyczyszczony:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #993333;">void</span> vga_scroll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// rewrite lines one up</span>
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> SCREEN_WIDTH <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>SCREEN_HEIGHT <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
                vga_mem<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> vga_mem<span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> SCREEN_WIDTH<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// clear last line</span>
        <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> SCREEN_WIDTH<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
                vga_mem<span style="color: #009900;">&#91;</span>SCREEN_WIDTH <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>SCREEN_HEIGHT <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">3872</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ((((0 &lt;&lt; 4) | (15 &amp; 0xFF)) &lt;&lt; 8) | 0x20) // white spaces on black background</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Do boju</h2>
<p>Mając pod kontrolą najważniejszą strukturę danych &#8211; GDT oraz odpowiednie (acz niekompletne) narzędzia do debuggowania możemy śmiało zagłębiać się w kolejne mechanizmy architektury x86. W końcu, za każdym razem, gdy coś nie zadziała &#8211; będziemy mogli sprawdzić dlaczego :).</p>
<p>Typowo, kompletny kod, w którego organizacji zaszły spore zmiany, jest dostępny tu:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">git clone git://github.com/luksow/OS.git --branch 0x06</pre></div></div>

<p>oraz bezpośrednio do obejrzenia <a href="http://github.com/luksow/OS/tree/0x06">tu</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2011/07/tworzenie-systemu-operacyjnego-%e2%80%93-czesc-0%c3%9706-porzadki-gdt-vga/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Moja praca inżynierska</title>
		<link>http://lukaszsowa.pl/2011/07/moja-praca-inzynierska/</link>
		<comments>http://lukaszsowa.pl/2011/07/moja-praca-inzynierska/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 15:07:40 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Prywata]]></category>
		<category><![CDATA[Różne]]></category>
		<category><![CDATA[chrome os]]></category>
		<category><![CDATA[containers]]></category>
		<category><![CDATA[elka]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[praca inżynierska]]></category>
		<category><![CDATA[życie]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=630</guid>
		<description><![CDATA[Pierwszy semestr działań związanych z pracą inżynierską za mną, pora więc na małe podsumowanie. Tak jak narzekam na wiele aspektów związanych z moimi studiami, to tym razem zdecydowanie są powody do zadowolenia. Poniżej skrótowy opis rozwój &#8222;sytuacji&#8221; w moim wypadku. Prolog Na koniec poprzedniego semestru należało zadeklarować opiekuna i temat pracowni inżynierskiej. Zadanie zdecydowanie niełatwe, [...]]]></description>
			<content:encoded><![CDATA[<p>Pierwszy semestr działań związanych z pracą inżynierską za mną, pora więc na małe podsumowanie. Tak jak narzekam na wiele aspektów związanych z moimi studiami, to tym razem zdecydowanie są powody do zadowolenia. Poniżej skrótowy opis rozwój &#8222;sytuacji&#8221; w moim wypadku.</p>
<h2>Prolog</h2>
<p>Na koniec poprzedniego semestru należało zadeklarować opiekuna i temat pracowni inżynierskiej. Zadanie zdecydowanie niełatwe, szczególnie gdy ma się tylko garstkę własnych doświadczeń i cudzych opinii na temat poszczególnych ludzi. Temat też należy dobrać z głową, jednak tu już prościej &#8211; <strong>zwykle</strong> wiadomo co kogo interesuje :). Ja szczęśliwie nie miałem problemu z doborem prowadzącego &#8211; <a href="http://lukaszsowa.pl/4-miesiace/">oczywiście</a> chciałem, aby opiekunem pracy został dr inż. Tomasz Jordan Kruk. Wiązało się to z niemałym, papierkowym rajdem po dziekanatach i sekretariatach, jednak bez większych problemów. Problem był natomiast z precyzyjnym tematem pracy. Wiedziałem tylko, że chcę aby dotyczył on zagadnień niskopoziomowych, związanychz  systemami operacyjnymi. Od słowa do słowa, dostałem propozycję zajęcia się systemem Google Chrome OS&#8230; i zgodziłem się bez większych oporów :). Pełne brzmienie tematu zostało wybrane jako <em>Budowa systemu Chrome OS -</em> uroczo prawda? Temat zdecydowanie nieoklepany tzn. nieznany, co mogło się wiązać z pewnymi trudnościami.</p>
<h2>Zawiązanie akcji</h2>
<p>Kolejne tygodnie po wybraniu tematu wiązały się z przekopywaniem  Internetu w poszukiwaniu informacji na temat tegoż tworu. Martwiące było  to, iż odnalazłem pełno marketingowego bełkotu, a rzetelnych informacji &#8211; jak na lekarstwo. W zasadzie jedyne sensowne źródło wiedzy, to <a href="http://www.chromium.org/chromium-os">strona projektu z dosyć ubogą dokumentacją</a>. Wyzwania &#8211; to lubię! Długa i dokładna analiza materiałów przekonały mnie, że najciekawszym elementem systemu Chrome OS są mechanizmy bezpieczeństwa. Za namową Prowadzącego, przez kolejne tygodnie pracowałem nad pierwszym rozdziałem mojej pracy, który nosi tytuł <em>Mechanizmy bezpieczeństwa systemu Google Chrome OS</em>. Muszę przyznać, że to dopiero było wyzwanie! Myśli i treści wiele, jednak ubranie ich w techniczno-naukowy język to prawdziwa sztuka. Uważam się za osobę, która dba o język polski, dlatego każde zdanie składałem z wielkim namaszczeniem. To nie to samo, co blog, gdzie mogę czasem strzelić emotkę, tudzież całkiem kolokwialne stwierdzenie, czy ohydny anglicyzm ;). Ostatecznie, tempo pisania sięgało jednego (sic!) słowa na minutę. Rewelacyjnie, prawda? Efektem tygodni pracy było 16 stron tekstu, z którego naprawdę jestem zadowolony. Mój Opiekun również docenił moją pracę i podsunął mi pomysł, aby zrobić z tego rodziału materiał konferencyjny bądź artykuł &#8211; czemu nie!</p>
<p>W tym miejscu wtrącę słówko na temat składania tekstu. Na mojej uczelni (jak zapewne na wielu innych) lansuje się system składu tekstu o intrygującej nazwie <a href="http://pl.wikipedia.org/wiki/LaTeX">LaTeX</a>. Przeczytanie książeczki o tym narzędziu zajęło mi 2 dni, które przepełniły mnie lekką obawą przed czymś z goła innym niż Word ;). Ostatecznie jednak, praca z LateXem okazała się prawdziwą przyjemnością i <span style="text-decoration: underline;"><strong>zdecydowanie ułatwiła mi pracę</strong></span>. Po prostu mogłem skoncentrować się na samym pisaniu, a  nie na ustawianiu marginesów. Z całego serca polecam wszystkim, do każdego rodzaju pisania (prace, dokumentacje, korespondencja, a nawet <a href="http://lukaszsowa.pl/wp-content/uploads/2010/07/CV1.pdf">CV</a>).</p>
<h2>Rozwój akcji</h2>
<p>Po napisanym rozdziale przyszła pora na wybranie części praktycznej (bo i z tego powinna się składać praca inżynierska). Tu zaczęły się niemałe problemy, bo rozszerzanie Chrome OS może być trudne i niewykonalne w przewidzianym czasie inżynierki. Szczęśliwie, podczas pisania poprzedniego rozdziału natrafiłem na bardzo ciekawą rzecz: koncepcję <a href="http://lwn.net/Articles/256389/">kontenerów procesów</a> (jest to mechanizm parawirtualizacji o którym niebawem napiszę więcej). Zrodził się więc pomysł, aby rozszerzyć części składowe kontenerów. Ucieszyło mnie to niezmiernie, gdyż oznacza to dużo grzebania w Linuksie! Kolejne 4 tygodnie spędziłem na poznawaniu budowy Linuksa i oswajaniu się z procesem rozwoju jądra. Temat mnie naprawdę wciągnął i z trudem mogłem oderwać się od czytania artykułów i kodu oraz oglądania nagrań z różnych konferencji o tematyce jądra Linuksa. Finalnie, udało mi się zdecydować na rozwijanie mechanizmu <a href="http://en.wikipedia.org/wiki/Cgroups">cgroups</a> i nad tym będę pracował w najbliższych tygodniach.</p>
<p>Uważny czytelnik może zauważyć, że od chwili wymyślenia tematu zacząłem dosyć mocno się od niego oddalać &#8211; i to jest właśnie najlepsza część mojej pracy inżynierskiej &#8211; mogę dowolnie zmieniać jej kształt i prowadzić rzeczywiste, <strong>odkrywcze</strong> badanie, a nie odtwórcze kompilowanie XX źródeł wiadomości. Aktualnie, wygląda na to, że temat będzie brzmiał <em>Mechanizmy zabezpieczeń w nowoczesnych dystrybucjach Linuksa na przykładzie Chrome OS</em> , ale kto wie co przyniesie przyszłość.</p>
<h2>I co dalej?</h2>
<p>Tak jak pisałem, będę teraz pracował nad praktyczną częścią pracy. Później przyjdzie pora na kolejne rozdziały &#8211; jakie? To się jeszcze okaże.</p>
<h2>Mała porada</h2>
<p>Wszystkim osobom, które dopiero szykują się do pisania pracy inżynierskiej polecam bardzo dobrze zastanowić się nad doborem opiekuna. Nieważne jak zdolni jesteście, dobry mentor może Wam wiele pomóc. Nie chodzi przecież o to, aby prowadził za rękę i pokazywał co, kiedy i ile napisać, tylko o to, aby odpowiednio kierunkował, podpowiadał i ostrzegał przed potencjalnymi zagrożeniami. Temat natomiast, przy współpracy z odpowiednią osobą, wyklaruje się sam.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2011/07/moja-praca-inzynierska/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cudowna (?) odmiana</title>
		<link>http://lukaszsowa.pl/2011/06/cudowna-odmiana/</link>
		<comments>http://lukaszsowa.pl/2011/06/cudowna-odmiana/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 15:33:53 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Prywata]]></category>
		<category><![CDATA[elka]]></category>
		<category><![CDATA[życie]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=622</guid>
		<description><![CDATA[Nie spodziewałem się, że kiedyś taki dzień nastanie, ale jednak! Miniony semestr był.. dosyć przyzwoity! To prawda, że masakrycznie zaniedbałem bloga &#8211; bo jak zwykle było multum roboty, a sił i minut w dobie nadal tyle samo. Mam jednak silne wrażenie, że nie cały ten czas zmarnowałem. Zło Jako urodzony optymista zacznę od tego, co [...]]]></description>
			<content:encoded><![CDATA[<p>Nie spodziewałem się, że kiedyś taki dzień nastanie, ale jednak! Miniony semestr był.. dosyć przyzwoity! To prawda, że masakrycznie zaniedbałem bloga &#8211; bo jak zwykle było multum roboty, a sił i minut w dobie nadal tyle samo. Mam jednak silne wrażenie, że nie cały ten czas zmarnowałem.</p>
<h2>Zło</h2>
<p>Jako urodzony optymista zacznę od tego, co było kiepskie, złe bądź fatalne. Jest na kierunku przedmiot o hucznej nazwie<strong> Bezpieczeństwo systemów i sieci</strong>. Sama nazwa budzi skojarzenia z medialnymi tematami hackerów i cyberwojen. Czego można więc spodziewać się po tym przedmiocie? Rzućmy kilkoma przykładami&#8230; Studenci zabezpieczający serwery, a następnie włamujący się do nich po to, aby poznać stosowane w praktyce techniki (zarówno dobrych jak i złych &#8222;gości&#8221;) &#8211; może nawet drużynowe potyczki, tak aby zwiększyć zaangażowanie? Analiza fizycznych jak i programowych zabezpieczeń sieci &#8211; poznawanie budowy i działania, a może nawet programowanie takich rozwiązań? Podstawy social engineeringu? Przykłady zagospodarowania czasu można mnożyć w zasadzie bez końca &#8211; potencjał przedmiotu ogromny! A wykonanie..? Wykład ma taką złą sławę, że moja frekwencja wyniosła okrągłe 0%. Tak, po prostu pojawiłem się tam jeden jedyny raz &#8211; na egzaminie zerowym. Co jest z nim nie tak? Materiał tam prezentowany jest bezdennie głupi i nudny. Co wykład, to nowy algorytm kryptograficzny do wkucia na pałę. Oprócz ciągu przekleństw do głowy przychodzi mi jeszcze jedno pytanie: dlaczego tak brutalnie zgwałcono, przedmiot z ogromnymi możliwościami? Czy bezpieczeństwo to rzeczywiście tylko kryptografia? Czy znajomość przebiegu algorytmów jest informatykom w ogóle potrzebna (tym chyba się zajmują się ludzie od kryptologii, tj. matematycy)? Żale możnaby wylewać jeszcze przez 3 ekrany tekstu, ale chyba po prostu szkoda słów. Na zakończenie tematu dodam, że laboratoria są dostosowane poziomem do wykładu. Polegają one na napisaniu sprawozdania z klikania w różnych, niedopracowanych programach, które chyba mają za zadanie ilustrować zagadnienia takie jak szyfrowanie czy podpis cyfrowy. Zgroza!</p>
<p>Oferta edukacyjna mojego wydziału jest tak bogata, że musiałem dokonać wyboru najmniejszego zła &#8211; padło na przedmiot o nazwie <strong>Programowanie aplikacji interakcyjnych</strong>, o jakże uroczym skrócie PAIN (który wszystko tłumaczy). Nie ma co się chyba rozwodzić zanadto nad brakiem sensowności tego przedmiotu, jako że aplikacje interakcyjne (tzn. okienkowe) są od jakiegoś czasu w zaniku. Biorąc ten przedmiot miałem nadzieję, że nauczę się nieco technik i dobrych praktyk programowania aplikacji z widokiem okienkowym, że przy okazji poznam parę trendów w tej dziedzinie i co nieco dowiem się o istniejących rozwiązaniach. Tymczasem (prawie) każdy wykład dotyczył tego, jak rozmieszcza się guziki i pola tekstowe w frameworkach/środowiskach takich jak: X, WinAPI, MFC, Qt, .NET (WinForms). Rewelacja, nie? Czy komukolwiek potrzebna jest wiedza o tym, jak wyświetlić menu w WinAPI, albo o tym na ile okien może dzielić splitter dynamiczny z MFC? Totalna bzdura! Nie muszę chyba dodawać, że potem trzeba było to odtwarzać na kolokwium&#8230; Najwstrętniejszą częścią tego przedmiotu były jednak laboratoria. Każde z nich polegało na zrobieniu większego, bądź mniejszego programu w każdej z ww. technologii &#8211; kupa zmarnowanego czasu na bieganie po dokumentacji i sklejanie kilkunastu okienek. Oczywiście, jakość kodu i zastosowane techniki absolutnie nie miały żadnego znaczenia i nie były sprawdzane. Liczyło się tylko to, jak ładnie dane okienko wygląda. Jako, że jest to przedmiot obieralny, to z całego serca życzę mu szybkiej śmierci przez brak chętnych.</p>
<h2>Dobro</h2>
<p>Po wyszczególnieniu tego co złe, przechodzimy do rzeczy przyzwoitych, dobrych i genialnych. Nie będę się rozpisywał o przedmiotach takich jak <strong>Prawo własności intelektualnej</strong> czy <strong>Procesory sygnałowe</strong>. Powiem tylko, że były one bardzo lekkie i przyjemne i skutecznie zasiliły konto moich cennych ECTS-ów.</p>
<p>Warto jednak napisać coś więcej o przedmiocie o tajemniczej nazwie <strong>Języki przetwarzania symbolicznego. </strong>Przedmiot ten przedstawia dwa sztandardowe języki przetwarzania symbolicznego &#8211; LISP i Prolog. O ile Lisp był mi trochę znany za sprawą <a href="http://lukaszsowa.pl/tag/emacs/">Emacsa</a>, o tyle Prolog był całkowitą nowością. Jako język deklaratywny prezentuje całkiem nowe podejście do programowania &#8211; podejście bardzo ciekawe. Przedmiot zaliczam na duży plus, ze względu na pokzanie mi czegoś nowego, na co wcześniej nie zwracałem uwagi. Nie mówię, że było prosto, czy też, że Prolog stał się moją nową pasją, jednak moje horyzonty myślowe zostały poszerzone. I o to w studiowaniu chodzi!</p>
<p><strong>Techniki kompilacji</strong> to przedmiot wobec którego miałem duże oczekiwania. Głównie ze względu na to, iż zawsze chciałem podjąć się napisania kompilatora i zobaczenia, jak ta cała magia się dzieje. Moje oczekiwania zostały częściowo spełnione. Wykład był naprawdę przyzwoitym wstępem do parsowania, zabrakło na nim jednak czegoś o optymalizacji kodu i o budowaniu samych kompilatorów. Braki wykładu nadrobił jednak projekt, na którym miałem możliwość napisania interpretera podzbioru języka Python. Projekt był naprawdę bardzo duży (zdecydowanie największy jaki robiłem na studiach) i niezwykle ciekawy. Końcowy efekt był dla mnie bardzo zadawalający, niestety nie miałem jednak czasu, aby dopracować kod, aby jego jakość zaspakajała moje osobiste potrzeby ;). Coś za coś, jak widać. Nie jest to może to samo co kompilator, jednak moja ciekawość i ambicja została w 100% zaspokojone. Zastanawiam się czy by przypadkiem nie upublicznić efektu mojej pracy w celach edukacyjnych, jednak niektóre programistyczne potworki, które się tam kryją mogłyby być bardzo antyedukacyjne ;&gt;.</p>
<p>Przechodząc do tego, co na tym semestrze było najlepsze, zacznę od przedmiotu <strong>Systemy wbudowane</strong>. Przedmiot ten ze względu na niezwykle rozległą tematykę był bardzo przeglądowy. Udało mi się zdobyć przekrojową wiedzę na wiele tematów związanych z systemami wbudowanymi oraz systemami czasu rzeczywistego. Wykład był prowadzony dobrze i otwarcie a mnogość tematów pozwoliła mi po raz kolejny poszerzyć swoją wiedzę <span style="text-decoration: underline;">ogólną</span>. Czy to dobrze? Zdecydowanie tak! Po co miałbym się uczyć o charakterystyce sygnałów sterujących w sieci polowej PROFIBUS &#8211; wystarczy mi wiedza, że taka sieć jest i co mogę dzięki niej osiągnąć! Laboratoria i projekt polegały na zapoznaniu się z systemem operacyjnym VxWorks &#8211; muszę przyznać, że to bardzo ciekawe, jednak niekiedy męczące, doświadczenie. Przedmiot na duuuuuuuuuży plus!</p>
<p>Na sam koniec, tradycyjnie &#8211; wisienka na torcie: <strong>Sterowniki urządzeń &#8211; podstawy programowania</strong>. Mógłbym długo &#8222;ochać&#8221; i &#8222;achać&#8221; na temat tego przedmiotu, ale może po prostu opiszę o czym on jest ;). Przedmiot jest o tworzeniu sterowników do urządzeń wszelkiej maści (mocno w kontekście systemów wbudowanych) w systemie Linux. Myślę, że ciężko byłoby mówić ogólnie, w oderwaniu od konkretnej implementacji, a więc wybór konkretnego systemu jest jak najbardziej słuszny. Wybór Linuksa też jest jak najbardziej na plus, gdyż ma to dużą wartość edukacyjną &#8211; przede wszystkim można przejrzeć jak coś jest zrobione, a nie polegać ślepo na dokumentacji. Przedmiot więc koncentruje się na grzebaniu głęboko w jądrze systemu &#8211; czyli to, co lubię najbardziej :). Wysoki poziom komplikacji materii i slajdy z kodem mogły niektórych przerażać, ale na tym polega przecież praktyczne podejście do sprawy. Do świetnego wykładu niezwykle ważnym dodatkiem jest projekt, który polega na stworzeniu sterownika do dowolnego urządzenia, na dowolnej platformie (niekoniecznie Linux, mógłbyć też np. dowolny mikrokontroler). Mojemu projektowi poświęce oddzielnego posta, bo myślę, że jest tego wart :).</p>
<p>Świetność tego przedmiotu należy w 100% przypisać prowadzącemu, panu <a href="http://www.ise.pw.edu.pl/~wzab/">dr inż. Wojciechowi Zabołotnemu</a>. Pan doktor Zabołotny, dzięki swojej niezwykle rozległej, wszechstronnej i praktycznej wiedzy uczynił z wykładu prawdziwe widowisko, na które pomimo piątku i późnej pory przychodziłem z ogromną przyjemnością. Wszystkim studentom, z całego serca życzę takich prowadzących.</p>
<p>Reasumując, dzięki temu przedmiotowi dowiedziałem się masę ciekawych rzeczy związanych z jądrem Linux, systemami wbudowanymi i problemami jakie można napotkać podczas pracy ze sprzętem. Dokładnie to, czym chciałbym się zajmować. Dziękuję!</p>
<h2>Ostatni semestr</h2>
<p>W końcu udało mi się ukończyć semestr, w którym większość rzeczy zaliczyć mogę na plus. 6 semestr z 7 semestrów studiów inżynierskich &#8211; wynik niezbyt imponujący &#8211; coż, podobno lepiej późno niż wcale. To, czego jednak znów mi zabrakło, to więcej wolnego czasu na rozwój własnych zainteresowań.</p>
<p>Na zakończenie wspomnę, że przede mną ostatni semestr studiów inżynierskich, który poświęcę w zasadzie w całości (został mi tylko jeden przedmiot &#8211; algorytmy heurystyczne) pisaniu pracy dyplomowej. Ze względu na uczelniane wymogi pisanie inżynierki zacząłem już w minionym semestrze &#8211; i o tym napiszę w następnej notce.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2011/06/cudowna-odmiana/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I znowu porażka</title>
		<link>http://lukaszsowa.pl/2011/02/i-znowu-porazka/</link>
		<comments>http://lukaszsowa.pl/2011/02/i-znowu-porazka/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 19:27:54 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Prywata]]></category>
		<category><![CDATA[elka]]></category>
		<category><![CDATA[życie]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=616</guid>
		<description><![CDATA[To uczucie gdy&#8230; Zapewne nieobce każdemu jest uczucie, gdy wydaje się, że &#8222;już gorzej być nie może&#8221;, a potem okazuje się, że no właśnie &#8211; wydawało się. Po semestrze numer cztery wydawało mi się, że gorzej być nie może &#8211; a tu proszę, taka niespodzianka! Semestr piąty przekroczył wszelkie granice beznadziejności, które ustanowili poprzednicy. Słyszałem [...]]]></description>
			<content:encoded><![CDATA[<h2>To uczucie gdy&#8230;</h2>
<p>Zapewne nieobce każdemu jest uczucie, gdy wydaje się, że &#8222;już gorzej być nie może&#8221;, a potem okazuje się, że no właśnie &#8211; wydawało się. Po semestrze numer cztery <a href="http://lukaszsowa.pl/zwatpilem-w-edukacje/">wydawało mi się</a>, że gorzej być nie może &#8211; a tu proszę, taka niespodzianka! Semestr piąty przekroczył wszelkie granice beznadziejności, które ustanowili poprzednicy. Słyszałem pogłoski, że po dwóch pierwszych latach jest już luźno i przyjemnie &#8211; akurat!</p>
<h2>To złe</h2>
<p>Długo &#8222;stygłem&#8221; zanim napisałem tego posta. Gdybym napisał go od razu po zakończeniu sesji, byłoby w nim zbyt wiele nieprzyzwoitych określeń ;&gt;. W ciągu tych 15 tygodni semestru &#8222;zaliczyłem&#8221; około 20 bezsennych nocy, spędzonych na roztrząsaniu rozmaitych &#8222;mądrości&#8221;. Wynika stąd, że średnio w każdym tygodniu nie spałem ponad jedną noc! Być może jestem zbyt ambitny, ale ja po prostu staram się wykonać zlecone mi zadania <em>dobrze</em>. Jak widać w prosty sposób odbija mi się to na zdrowiu, a także kontaktach towarzyskich, zainteresowaniach no i blogu. Do pierwszej fali kolokwiów udawało mi się pisać regularnie i to z nawet dobrym skutkiem. Potem odpadłem. Każdą wolną chwilę, którą jakimś cudem udawało mi się wyrwać szkole wolałem poświęcić na sen, spotkanie z ludźmi i niestety &#8211; na blog, czy też rozwijanie zainteresowań czasu już nie było. Czy studia tu są tego warte? Przemyślenia na ten temat pozostawię sobie na oddzielną notkę.</p>
<p>Teraz może wspomnę o garstce (z baaaaardzo wielu) absurdów, które spotkały mnie w tym semestrze. Przede wszystkim wyjątkowo dokuczliwa okazała się tzw. profesorska duma. Niestety, wiele osób pracujących na uczelni w roli wykładowcy/laboranta w ogóle nie przykłada się do swojej pracy. Ich stosunek do prowadzenia zajęć jest delikatnie mówiąc olewczy. Materiał jest przygotowany niedbale, czesto jest bardzo mizerny merytorycznie, albo mówiąć wprost &#8211; zawiera rażące błędy. Nie jest to jednak najbardziej denerwująca cecha &#8211; bardziej wkurzające jest to, że często właśnie te osoby nie potrafią się przyznać do swojego błędu czy też niewiedzy. Warto być przecież prawdziwym, nieomylnym twardzielem, nie? Dodajmy do tego poniżające odniesienie do studenta (bo co takiemu pro-fesorowi student, pff!) i katastrofa gotowa. Przykłady z życia wziętę? Jeden z prowadzących postanowił przepisać na slajdy tłumaczenie książki, a następnie na wykładzie pracowicie, przez dwie godziny odczytywał je nużącym głosem. To ma być wykład? Jeśli tak, to wykładowcą może być absolutnie każdy, kto potrafi czytać, bo to jedyne, co ten prowadzący zaprezentował swoją osobą. Inny wykładowca z kolei prowadził wykład chaotycznie i niedbale, a żeby zaliczyć przedmiot zalecał przeczytanie książki.. którą oczywiście sam napisał (to, że lansuje tam własny, często rozbieżny z rzeczywistością, ogląd tematu &#8211; przemilczę). Dodatkowo oceny z tego przedmiotu wydawały się pochodzić wprost z /dev/random, a liczba &#8222;uwalonych&#8221; po pierwszej turze przekraczała 50%. Czyja to wina? To chyba oczywista sprawa. Na innym przedmiocie spotkałem się z kolei z laborantem, który nie potrafił się przyznać do swojej niewiedzy &#8211; a była ona ogromna, bo niestety wydaje mi się, że został do przedmiotu wybrany przez przypadek. Oczywiście &#8211; mógł się przygotować, ale komu by się chciało? A może po prostu nie można zbyt wiele oczekiwać od programistów Javy ;&gt;?</p>
<p>Nuda, nuda, nuda. Tak można scharakteryzować wykład z przedmiotu, który wydawał mi się ciekawy &#8211; z tytułu i opisu. Nużący, monotonny głos, patrzenie w podłogę, zerowy kontakt ze studentem &#8211; tak można scharakteryzować prowadzącego ten wykład. Człowiek ten na dobre obrzydził mi dziedzinę informatyki, którą kiedyś bardzo lubiłem. Szkoda.</p>
<p>Merytoryka &#8211; a raczej jej brak &#8211; najbardziej mnie boli. Zdarza się to dosyć często, a koronnym przykładem na moich studiach jest przedmiot o grafice komputerowej. O ile wykład był znośny (może nawet dobry dla kogoś zainteresowanego jakkolwiek tematem?), to już laboratoria zdecydowanie nie. Jak myślicie, co można robić na laboratoriach z przedmiotu o tytlue &#8222;grafika komputerowa&#8221;? Gdy sam sobie zadałem to pytanie miałem kilka pomysłów &#8211; podstawy silników graficznych (budowanie/modyfikacje/analiza), projektowanie/implementowanie algorytmów związanych z grafiką, pisanie sterowników graficznych. Tymczasem okazuje się, że na laboratoriach rysuje/edytuje się obrazki w programch graficznych i modeluje obiekty 3D! Prawdziwy absurd! To jest informatyka na Politechnice Warszawskiej, czy może ASP, tudzież grafika na PWSFTViT? Może warto jeszcze zrobić jakiś przedmiot z nauką Excela i Worda, przecież to też robi się na komputerze! Wydaje mi się, że osoba, która układała materiał na te laboratoria kompletnie nie miała pomysłu na czym mogą polegać albo brakowało ludzi z odpowiednimi umiejętnościami (i lepiej, żeby to był ten pierwszy powód&#8230;).</p>
<p>Na dobre zakończenie semestru spotkała nas studentów jeszcze bardzo &#8222;miła&#8221; niespodzianka. Mianowicie, na 6 semestrze mamy do zrobienia 4-6 przedmiotów, które sami wybieramy. W kwietniu zeszłego roku została przedstawiona oferta programowa liczącą kilkanaście przedmiotów. Okej, niezbyt bogata, ale można już było się zastanowić, co warto wybrać. Przyszedł moment wyboru i&#8230; okazało się, że połowy z tych przedmiotów nie ma &#8211; części nie można wziąć, a inne w ogóle nie zostały utworzone. Wszelkie skargi i pretensje zostały odrzucone metodą przerzucania odpowiedzialności na kogoś innego &#8211; i tak studenci zostali na lodzie. Cały &#8222;szeroki&#8221; wybór przedmiotów został ograniczony do wybierania &#8222;mniejszego zła&#8221;, czyli przedmiotów, które cieszą się lepszą sławą od pozostałych. I to mają być studia elastyczne &#8211; kpina! Nie wątpię oczywiście, że odpowiedzialni za ten bałagan się nie znajdą.</p>
<p>Podobna, miła sytuacja &#8222;administracyjna&#8221; miała miejsce na początku semestru, gdy to dziekanat dobroczynnie dał stypendia studentom, a nieco później okazało się, że trzeba je odebrać. Sprawa była moim zdaniem mocno skandaliczna, ale powiedzmy, że postarałem się już o tym zapomnieć.</p>
<h2>I to dobre</h2>
<p>Szczęśliwie, semestr ten miał kilka miłych akcentów. Przede wszystkim udało mi się dostać do najlepszego z możliwych opiekunów pracy inżynierskiej! Niezmiernie mnie to cieszy, bo wiem że pisanie jej, będzie dzięki temu prawdziwą przyjemnością. Postaram się o tym wspomnieć na blogu w niedługim czasie :).</p>
<p>Dodatkowo na semestrze tym miałem przyjemność uczestniczyć w 3 niezłych wykładach, które jakoś wzbogaciły moją wiedzę. Pierwszy z nich dotyczył technik internetowych &#8211; przekrojowo o różnych sprawach związanych z aplikacjami internetowymi; drugi był o systemie UNIX (nota bene, ten sam prowadzący co techniki internetowe) &#8211; opis API, a także wewnętrznych mechanizmów; trzeci natomiast dotyczył sztucznej inteligencji &#8211; co prawda pierwsza połówka dotyczyła wnioskowania i była naprawdę paskudna (zarówno pod względem materiału jak i prowadzącego), ale druga była naprawdę ciekawa i zainteresowała mnie tematem.</p>
<p>Ostatnim miłym elementem semestru były projekty &#8211; doskonała okazja, żeby posiedzieć z kolegami, napić się piwa, zjeść pizzę, a przy tym rozwiązać ciekawe zagadnienia :)! Kod, to jest jednak to, co cieszy programistów najbardziej :P.</p>
<h2>Plany?</h2>
<p>Nie. Kiedyś pisałem, o tym jakie przedmioty będę robić w nadchodzącym semestrze i czego od nich oczekuję, jednak po przeszłych doświadczeniach wiem, że należy wyłącznie oczekiwać, że będą one mało upierdliwe. O dobry, wysoki poziom jest bardzo ciężko, niech więc chociaż <a href="http://pl.wikiquote.org/wiki/Mark_Twain">nie przeszkadzają w mojej własnej edukacji</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2011/02/i-znowu-porazka/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Koncepcja pamięci wirtualnej</title>
		<link>http://lukaszsowa.pl/2010/12/koncepcja-pamieci-wirtualnej/</link>
		<comments>http://lukaszsowa.pl/2010/12/koncepcja-pamieci-wirtualnej/#comments</comments>
		<pubDate>Sun, 12 Dec 2010 04:49:51 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[osdev]]></category>
		<category><![CDATA[systemy operacyjne]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=602</guid>
		<description><![CDATA[Pamięć Jednym z zadań systemu operacyjnego jest zarządzanie zasobami &#8211; tzn. przydzielanie ich i odbieranie wykonywającym się programom. Pamięć, zaraz po czasie procesora, jest najważniejszym i zarazem najpopularniejszym zasobem, który używany jest przez procesy. Jak pokazuje historia, rozwój pamięci jest bardzo szybki &#8211; IBM 7094 z 1962 roku miał standardowo około 150 KiB pamięci, a [...]]]></description>
			<content:encoded><![CDATA[<h3>Pamięć</h3>
<p>Jednym z zadań systemu operacyjnego jest zarządzanie zasobami &#8211; tzn. przydzielanie ich i odbieranie wykonywającym się programom. Pamięć, zaraz po czasie procesora, jest najważniejszym i zarazem najpopularniejszym zasobem, który używany jest przez procesy. Jak pokazuje historia, rozwój pamięci jest bardzo szybki &#8211; IBM 7094 z 1962 roku miał standardowo około 150 KiB pamięci, a sam komputer kosztował 3.5 mln USD. Na dzień dzisiejszy, przeciętny komputer ma 10000 razy więcej pamięci i kosztuje 10000 razy mniej :). Z drugiej strony, programy rozrastają się jeszcze szybciej niż dostępna pamięć &#8211; <a href="http://www.popsci.com/node/31716">1 MiB wystarczał kiedyś, żeby polecieć w kosmos</a>, natomiast Windows Vista ledwo zipie na komputerze z 1 GiB pamięci ;).</p>
<p>Pamięci powinno być dużo &#8211; najlepiej nieskończenie dużo. Do tego jeszcze warto, aby była ona nieskończenie szybka, nieulotna i tania. Niestety &#8211; nie da się! W ramach rozwiązania tego problemu wprowadzono koncepcję hierarchii pamięci. Zgodnie z nią komputery wyposażone są w nieco bardzo szybkiej, małej i drogiej pamięci (rejestry, cache); w dużo szybkiej i niedrogiej pamięci (RAM) oraz w ogromnie dużo, bardzo wolnej, ale bardzo taniej pamięci (HDD, DVD itd.). Do wygodnej pracy z taką hierarchią niezbędne jest stworzenie pewnej abstrakcji, która pozwalałaby nie przejmować się tym, czy operujemy na cache&#8217;u, RAM-ie, czy wczytujemy wymiecione programy z dysku &#8211; ale o tym za chwilę, na razie zajmijmy się najprostszym przypadkiem.</p>
<h3>Brak abstrakcji</h3>
<p>W tym modelu zarządzania pamięcią, każdy wykonywający się program operuje bezpośrednio na pamięci fizycznej (RAM) &#8211; wykonanie instrukcji <em>mov [0x9000], 24</em> spowoduje wpisanie wartości 24 pod adres 0&#215;9000. Wydaje się to intuicyjnie oczywiste, jednak pociąga to za sobą wiele skomplikowanych problemów. Przede wszystkim ciężko tu zapewnić ochronę &#8211; procesy mogą odczytywać i zapisywać pamięć, która nie należy do nich. Do tego, każdy proces musi wiedzieć gdzie został załadowany tak aby instrukcje odwoływania się do pamięci były poprawne. Każdy proces musi również znać i przestrzegać limitów pamięci, które raczej powinny być sztywne. Wszystkie te problemy starano się jakoś rozwiązać i tak np. wprowadzono podział pamięci na pewne zakresy, które przypisywane były procesom poprzez odpowiednie znaczniki. Inny sposób zakłada natomiast wymiatanie całej pamięci na dysk, wybranie kolejnego procesu do wykonania, a następnie wczytanie całej jego pamięci z dysku &#8211; jest to rozwiązania wyjątkowo nieefektywne. Dokładniejsze studium przypadku ujawnia wiele kolejnych problemów &#8211; np. alokacja dużej tablicy (ciągłej!) w pofragmentowanej przestrzeni może się okazać niemożliwe &#8211; potrzebny jest wtedy mechanizm relokacji. Na wiele problemów związanych z brakiem abstrakcji znajdziemy pewne (lepsze lub gorsze) remedium, niestety niektórych rzeczy obejść się nie uda &#8211; np. potrzeby powiększenia przestrzeni adresowej ponad dostępna pamięć fizyczną. Na koniec warto jednak dodać, iż całkowity brak abstrakcji na pamięci jest wciąż popularny i uzasadniony &#8211; w systemach wbudowanych. Procesy działające w takich systemach są zwykle małe i zaufane &#8211; nie potrzebna jest im szczególna ochrona, czy wygoda programowania.</p>
<h3>Pamięć wirtualna</h3>
<p>Wirtualny &#8211; słowo często używane w informatyce, nie zawsze poprawnie, nie zawsze świadomie :). Ciekawy tego co mówi na ten temat <a href="http://sjp.pwn.pl/slownik/2536590/wirtualny">słownik języka polskiego</a> &#8211; sprawdziłem i zdziwiłem się co nie miara. Nic więc dziwnego, że dezinformacja się szerzy :D. Mówiąc wymijająco (ale za to prawdziwie) &#8211; to co znaczy wirtualny &#8211; zależy od kontekstu :). Wracając jednak do tematu&#8230;</p>
<p>Pamięć wirtualna to mechanizm zapewniający wykonywającemu się programowi dostęp do pełnej, niezależnej od innych procesów przestrzeni adresowej. Przestrzeń ta w szczególności nie musi odpowiadać pamięci fizycznej (co jest sytuacją typową) &#8211; może być nieciągła, pofragmentowana i przechowywana na nośnikach trwałych (dysku). Zachodzi więc pewne mapowanie adresu wirtualnego (na którym operuje proces) na adres w pamięci fizycznej. To podejście rozwiązuje nam wszystkie problemy związane z ochroną (oddzielne przestrzenie adresowe = brak możliwości &#8222;wchodzenia sobie w drogę&#8221;), ładowaniem do pamięci (procesy mogą być np. ładowane pod stały adres), nieciągłością przy alokacji tablic (sprawę załatwia mapowanie &#8211; ciągły obszar mapowany jest na nieciągły, który był aktualnie dostępny). Nie ma rzeczy idealnych, więc łatwo się domyślić, że muszą być jakieś wady. Tak jest i tym razem. Pamięć wirtualna znacząco komplikuję budowę architektur (potrzebna jest jednostka zarządzania pamięcią), a także powodują pewien narzut związany z pośredniością, co może mieć znaczenie np. w systemach czasu rzeczywistego.</p>
<p>Dla uzupełnienia dodam, że pamięć wirtualną buduje się w oparciu o pamięć RAM i urządzenia dyskowe. Wspomniany wcześniej cache jest w zasadzie dla programisty i systemu operacyjnego przezroczysty (podsystemy architektury decydują o tym, co ma być cache&#8217;owane), a rejestrami zajmują się kompilatory i programiści assemblera (i tak nie przydałyby się w budowaniu pamięci wirtualnej).</p>
<h3>Praktycznie</h3>
<p>Praktycznie rzecz ujmując pamięć wirtualna jest jak najbardziej pożądana (oprócz wspomnianych systemów czasu rzeczywistego) i w zasadzie nie spotyka się w dużych komputerach jej braku. Pamięć wirtualną realizować można na dwa sposoby &#8211; za pomocą <a href="http://lukaszsowa.pl/segmentacja-nielubiana-siostra-stronicowania/">segmentacji</a> oraz za pomocą stronicowania (o którym w następnym wpisie), z czego tak jak pisałem, ta druga metoda jest zdecydowanie popularniejsza.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2010/12/koncepcja-pamieci-wirtualnej/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8222;Daj się poznać&#8221; &#8211; pierwsze miejsce! Dziękuję!</title>
		<link>http://lukaszsowa.pl/2010/12/daj-sie-poznac-pierwsze-miejsce-dziekuje/</link>
		<comments>http://lukaszsowa.pl/2010/12/daj-sie-poznac-pierwsze-miejsce-dziekuje/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 19:10:55 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Prywata]]></category>
		<category><![CDATA[Różne]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[daj się poznać]]></category>
		<category><![CDATA[konkurs]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=598</guid>
		<description><![CDATA[Konkurs zorganizowany przez Maćka Aniserowicza dobiegł końca. Wg oficjalnych wyników zająłem w głosowaniu pierwsze miejsce! Cóż tu dużo pisać &#8211; ogromnie się cieszę, że praca wykonana przez te 3 miesiące spodobała się Czytelnikom. Tak jak już wspominałem jest to najlepsze motywacja, aby dalej aktywnie pracować nad projektem i blogiem &#8211; i tak w rzeczy samej [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.maciejaniserowicz.com/page/Konkurs-daj-sie-poznac.aspx">Konkurs</a> zorganizowany przez <a href="http://www.maciejaniserowicz.com/">Maćka Aniserowicza</a> dobiegł końca. Wg <a href="http://www.maciejaniserowicz.com/post/2010/12/01/Wyniki-i-podsumowanie-konkursu-Daj-Sie-Poznac.aspx">oficjalnych wyników</a> zająłem w głosowaniu pierwsze miejsce! Cóż tu dużo pisać &#8211; ogromnie się cieszę, że praca wykonana przez te 3 miesiące spodobała się Czytelnikom. Tak jak już wspominałem jest to najlepsze motywacja, aby dalej aktywnie pracować nad projektem i blogiem &#8211; i tak w rzeczy samej będzie :).</p>
<p>Bardzo dziękuję Maćkowi i chylę czoła za trud i zaangażowanie, które włożył w przygotowanie konkursu. Ta inicjatywa to świetny pomysł na rozruszanie polskiego środowiska programistów. W moim wypadku, konkurs sprawił, że mój blog ożył, zyskał wielu nowych czytelników i osiągnał poziom, z którego w końcu jestem zadowolony.</p>
<p>Dziękuję również Czytelnikom &#8211; to w końcu dzięki Wam udało mi się zdobyć tak dobry wynik :). Szczerze powiedziawsz, nie spodziewałem się, że projekt nie .NETowy ma szanse na miejsce choćby w pierwszej piątce!</p>
<p>Dziękuję i gratuluję wszystkim Współzawodnikom, bez których konkurs nie byłby taki ciekawy. Sporo nowych, niezwykle ciekawych blogów dołączyło do mojego czytnika RSS :).</p>
<p>Teraz, po zakończeniu konkursu, powstało całkiem nowe zadanie &#8211; nie zawieść oczekujących na kolejne wpisy. Tak sobie myślę, że może być to trudniejsze niż sam udział w konkursie, bo jak wiadomo bez &#8222;bata nad głową&#8221; pracuje się ciężej :). Zrobię jednak wszystko co w mojej mocy, żeby nie rozczarować!</p>
<p>PS. Kolejny post na temat systemów operacyjnych już w przyszłym tygodniu! Natłok rozmaitych zajęć sprawił, że o wynikach konkursu dowiedziałem się od kolegi, a ten post ukazał się 3 dnia po ogłoszeniu wyników &#8211; proszę więc o wyrozumiałość ;).</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2010/12/daj-sie-poznac-pierwsze-miejsce-dziekuje/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>&#8222;Daj się poznać&#8221; &#8211; finał!</title>
		<link>http://lukaszsowa.pl/2010/11/daj-sie-poznac-final/</link>
		<comments>http://lukaszsowa.pl/2010/11/daj-sie-poznac-final/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 18:21:34 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Prywata]]></category>
		<category><![CDATA[Różne]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[daj się poznać]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=596</guid>
		<description><![CDATA[Udało się! Dostałem się do finałowej siedemnastki konkursu Daj się poznać. Dziękuje wszystkim współzawodnikom, którzy oddali na mnie swój głos :) Jednocześnie zwracam się do wszystkich Czytelników, którym moje posty przypadły do gustu, z prośbą o oddanie na mnie głosu. Możecie to zrobić tutaj. Wasze uznanie dla mojej pracy, to najlepsza zachęta do dalszego, intensywnego [...]]]></description>
			<content:encoded><![CDATA[<p>Udało się! Dostałem się do finałowej siedemnastki konkursu <a href="http://www.maciejaniserowicz.com/page/Konkurs-daj-sie-poznac.aspx">Daj się poznać</a>. Dziękuje wszystkim współzawodnikom, którzy oddali na mnie swój głos :) Jednocześnie zwracam się do wszystkich Czytelników, którym moje posty przypadły do gustu, z prośbą o oddanie na mnie głosu. Możecie to zrobić <a href="http://dajsiepoznac.devmedia.pl/voting/stage-2">tutaj</a>. Wasze uznanie dla mojej pracy, to najlepsza zachęta do dalszego, intensywnego pisania. Z góry dzięki! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2010/11/daj-sie-poznac-final/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>&#8222;Daj się poznać&#8221; &#8211; sukces!</title>
		<link>http://lukaszsowa.pl/2010/11/daj-sie-poznac-sukces/</link>
		<comments>http://lukaszsowa.pl/2010/11/daj-sie-poznac-sukces/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 07:00:35 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[daj się poznać]]></category>
		<category><![CDATA[konkurs]]></category>
		<category><![CDATA[osdev]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=588</guid>
		<description><![CDATA[Statystyka W zeszłym tygodniu minął 10 tydzień pracy nad moim projektem. Na blogu, łącznie z tym, wiszą 23 posty otaggowane &#8222;daj się poznać&#8221;. 20 z wymienionych, to posty stricte konkursowe, 6 z nich to posty dotykające projektu bezpośrednio, pozostałe 14, to potężna dawka wiedzy przydatnej podczas tworzenia systemu operacyjnego. 3 posty trafiły na dotnetomaniaka, generując [...]]]></description>
			<content:encoded><![CDATA[<h3>Statystyka</h3>
<p>W zeszłym tygodniu minął 10 tydzień pracy nad moim projektem. Na blogu, łącznie z tym, wiszą 23 posty <a href="http://lukaszsowa.pl/tag/daj-sie-poznac/">otaggowane &#8222;daj się poznać&#8221;</a>. 20 z wymienionych, to posty stricte konkursowe, 6 z nich to <a href="http://lukaszsowa.pl/tag/tworzenie-systemu-operacyjnego/">posty dotykające projektu bezpośrednio</a>, pozostałe 14, to potężna dawka wiedzy przydatnej podczas tworzenia systemu operacyjnego. 3 posty trafiły na dotnetomaniaka, generując znaczny ruch :) Najbardziej popularnym postem, był nieco kontrowersyjny wpis <em><a href="http://lukaszsowa.pl/edytor-tekstu-zamiast-wypasionego-ide">Edytor tekstu zamiast wypasionego IDE?</a></em>. Skandalizowanie zawsze w cenie? ;&gt;</p>
<h3>Kod?</h3>
<p>Zabrzmi to śmiesznie, ale projekt ma w obecnym stadium poniżej 100 linii. To dużo i mało jednocześnie. Dużo, gdyż wiedza potrzebna i zalecana do napisania tych &lt;100 linii jest naprawdę obszerna. Mało, gdyż to wciąż tylko &lt;100 linii, gdy inne projekty konkursowe mają ich tysiące. Tak jak <a href="http://lukaszsowa.pl/moj-udzial-w-konkursie-daj-sie-poznac/">wspominałem</a>, projekt nie stanowi pełnoprawnego &#8222;produktu&#8221;, a jest przedmiotem swoistych badań &#8211; i w takiej formie idealnie się sprawdza.</p>
<h3>Słodki smak sukcesu</h3>
<p>Swój udział w konkursie uważam za ogromny sukces, niezależnie od miejsca, które zajmę. Dzięki <a href="http://www.maciejaniserowicz.com/">Maćkowi</a>, zmobilizowałem się do regularnego pisania postów (choć bywało ciężko). Pokazałem sam sobie, że się da. Jak się okazało &#8211; najtrudniej jest zacząć. Bolączką mojego bloga były naprawdę sporadyczne i nietematyczne posty &#8211; teraz to się zmieniło. Kolejnym aspektem sukcesu jest pozytywna informacja zwrotna, którą dostałem. Wszystkim, którzy pozytywnie wyrazili się na temat mojej pracy serdecznie dziękuję &#8211; to niesamowita motywacja do dalszego działania.</p>
<h3>Co dalej?</h3>
<p>Projekt i seria postów na temat tworzenia systemu operacyjnego na pewno nie skończy się wraz z konkursem. Całość mam zamiar jeszcze dłuuuuugo kontynuować. Nie mogę zagwarantować, że posty dalej będą pojawiać się tak regularnie, jak przez czas trwania konkursu, postaram się jednak pisać jak najczęściej.</p>
<h3>Na koniec</h3>
<p>Jeśli seria postów konkursowych przypadła Ci do gustu drogi Czytelniku, nie zapomnij zagłosować na mnie po 15 listopada! Tak czy inaczej, zachęcam do <a href="http://feeds.feedburner.com/LukaszSowa/">subskrypcji</a> mojego bloga i regularnego zaglądania tutaj! Będzie coraz lepiej &#8211; gwarantuję!</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2010/11/daj-sie-poznac-sukces/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tworzenie systemu operacyjnego – część 0×05: Multiboot Specification</title>
		<link>http://lukaszsowa.pl/2010/11/tworzenie-systemu-operacyjnego-%e2%80%93-czesc-0%c3%9705-multiboot-specification/</link>
		<comments>http://lukaszsowa.pl/2010/11/tworzenie-systemu-operacyjnego-%e2%80%93-czesc-0%c3%9705-multiboot-specification/#comments</comments>
		<pubDate>Sun, 07 Nov 2010 22:00:06 +0000</pubDate>
		<dc:creator>Łukasz</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[daj się poznać]]></category>
		<category><![CDATA[osdev]]></category>
		<category><![CDATA[systemy operacyjne]]></category>
		<category><![CDATA[tworzenie systemu operacyjnego]]></category>

		<guid isPermaLink="false">http://lukaszsowa.pl/?p=580</guid>
		<description><![CDATA[Multiboot Specification Multiboot Specification jest próbą stworzenia ustandaryzowanego sposobu bootowania systemów operacyjnych. Chodzi o to, aby każdy bootloader zgodny z Multiboot Specification był w stanie bootować każdy system operacyjny również zgodny z Multiboot Specification. Ma to ułatwić tworzenie środowisk z wieloma systemami operacyjnymi. Multiboot Specification nie definiuje tego, jak ma być napisany bootloader, a jedynie [...]]]></description>
			<content:encoded><![CDATA[<h3>Multiboot Specification</h3>
<p><a href="http://www.gnu.org/software/grub/manual/multiboot/multiboot.html">Multiboot Specification</a> jest próbą stworzenia ustandaryzowanego sposobu bootowania systemów operacyjnych. Chodzi o to, aby każdy bootloader zgodny z Multiboot Specification był w stanie bootować każdy system operacyjny również zgodny z Multiboot Specification. Ma to ułatwić tworzenie środowisk z wieloma systemami operacyjnymi.</p>
<p>Multiboot Specification nie definiuje tego, jak ma być napisany bootloader, a jedynie odpowiedni interfejs. Referencyjną implementacją Multiboot Specifciation jest <a href="http://www.gnu.org/software/grub/">GNU GRUB</a>. Wiele systemów operacyjnych (np. Linux), bootloaderów i maszyn wirtualnych (np. QEMU) jest zgodnych z tą specyfikacją, więc nie jest ona tylko teoretycznym dokumentem. Niezwykle istotną cechą bootloaderów zgodnych z Multiboot Specification jest to, że są one w stanie bootować kernel skompilowany do <a href="http://lukaszsowa.pl/pliki-wykonywalneobiektowe/">popularnych formatów plików wykonywalnych</a> np. ELF. Dzięki temu możemy korzystać ze wszelkich dobrodziejstw, które formaty oferują.</p>
<p>O konkretnych cechach Multiboot Specification wspomnę przy okazji kodu, poniżej.</p>
<h3>Multiboot Specification mam i ja!</h3>
<p>W swoim projekcie systemu operacyjnego postanowiłem porzucić własny bootloader na rzecz bootloadera zgodnego z Multiboot Specification. Może się to wydawać dziwne, bo napisanie całego kodu związanego z bootowaniem zajęło mi sporo czasu, ale tak naprawdę ma to głębokie uzasadnienie. Przede wszystkim, mój bootloader jest bardzo ubogi i prosty &#8211; nie potrafi bootować żadnych formatów plików wykonywalnych, a jedynie płaskie binarki, co jest niezwykle uciążliwe, gdyż muszę polegać na magicznych stałych. Ponadto nie dostarcza on żadnych informacji systemowi operacyjnemu &#8211; wszystko trzeba zrobić samodzielnie. Oczywiście, można napisać ten kod samodzielnie&#8230; Jednak uważam, że nie jest on wystarczająco pasjonujący, aby się nim zajmować :). Dzięki Multiboot Specification będziemy mogli przestać zajmować się szczegółami, a przejść do rzeczy :).</p>
<h3>Kod &#8211; czyli co my musimy zrobić dla Multiboot Specification, a co on zrobi dla nas?</h3>
<p>Na chwilę musimy powrócić do assemblera, aby dostarczyć kilku informacji wymaganych przez bootloader i od razu możemy skoczyć do kodu w C.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="asm" style="font-family:monospace;">global loader				<span style="color: #666666; font-style: italic;">; set visible to linker</span>
<span style="color: #000000; font-weight: bold;">extern</span> main				<span style="color: #666666; font-style: italic;">; main from main.c</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; some useful macro values</span>
FLAGS		equ	<span style="color: #0000ff;">0</span>		<span style="color: #666666; font-style: italic;">; this is the multiboot 'flag' field</span>
MAGIC		equ	<span style="color: #0000ff;">0x1BADB002</span>	<span style="color: #666666; font-style: italic;">; 'magic number' lets bootloader find the header</span>
CHECKSUM	equ	<span style="color: #339933;">-</span><span style="color: #009900; font-weight: bold;">&#40;</span>MAGIC <span style="color: #339933;">+</span> FLAGS<span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #666666; font-style: italic;">; checksum required</span>
STACKSIZE	equ	<span style="color: #0000ff;">0x4000</span>		<span style="color: #666666; font-style: italic;">; 16 KiB for stack</span>
&nbsp;
section <span style="color: #339933;">.</span>text
<span style="color: #000000; font-weight: bold;">align</span> <span style="color: #0000ff;">4</span>
<span style="color: #666666; font-style: italic;">; setting multiboot header</span>
multiboot_header<span style="color: #339933;">:</span>
	<span style="color: #000000; font-weight: bold;">dd</span>	MAGIC
   	<span style="color: #000000; font-weight: bold;">dd</span>	FLAGS
   	<span style="color: #000000; font-weight: bold;">dd</span>	CHECKSUM
&nbsp;
loader<span style="color: #339933;">:</span>
	<span style="color: #00007f; font-weight: bold;">mov</span>	<span style="color: #00007f;">esp</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">stack</span> <span style="color: #339933;">+</span> STACKSIZE	<span style="color: #666666; font-style: italic;">; set up the stack</span>
	<span style="color: #00007f; font-weight: bold;">push</span>	<span style="color: #00007f;">eax</span>			<span style="color: #666666; font-style: italic;">; pass multiboot magic number as second parameter</span>
	<span style="color: #00007f; font-weight: bold;">push</span>	<span style="color: #00007f;">ebx</span>			<span style="color: #666666; font-style: italic;">; pass multiboot info structure as first parameter</span>
&nbsp;
	<span style="color: #00007f; font-weight: bold;">call</span>	main			<span style="color: #666666; font-style: italic;">; call C code</span>
&nbsp;
section <span style="color: #339933;">.</span>bss
<span style="color: #000000; font-weight: bold;">align</span> <span style="color: #0000ff;">4</span>
<span style="color: #000000; font-weight: bold;">stack</span><span style="color: #339933;">:</span>
   	resb 	STACKSIZE		<span style="color: #666666; font-style: italic;">; reserve stack space</span></pre></td></tr></table></div>

<p>Najbardziej istotne są makra z linii 5-7. Pierwsze z nich określa flagi, które informują bootloader, czego od niego oczekujemy. Wśród możliwych opcji jest: wyrównanie modułów do rozmiaru strony, dołączenie mapy pamięci oraz dostępnych trybów video. Po więcej informacji zapraszam <a href="http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Specification">tu</a>. Póki co, nie potrzebujemy niczego, stąd wartość 0. Drugie to wartość magiczna, która pozwala bootloaderowi zidentyfikować nagłówek. Liczba 0x1BADB002 jest urocza, prawda? :) Trzecia wartość, to suma kontrolna, która powinna mieć wartość, taką że dodana do pól: FLAGS i MAGIC daje zero.</p>
<p>Kolejne linijki są oczywiste. W sekcji kodu musimy zamieścić kolejno wartość magiczną, flagi oraz sumę kontrolną, co dzieje się w liniach 14-16. Etykieta loader to rzeczywisty punkt wejściowy naszego jądra. W wierszu 19 ustalamy początek stosu, na którego miejsce rezerwujemy w sekcji bss (linia 28). Istotne jest, aby miejsce rezerwowane było w sekcji bss, bo inaczej rezerwacja będzie polegała na stworzeniu dużego pliku z wieloma zerami, a przecież nie o to nam chodzi. Etykieta bss załatwia sprawę &#8211; kompilator &#8222;wie&#8221;, że tylko rezerwujemy przestrzeń w odpowiednim miejscu w pamięci. Następnie w liniach 20 i 21 odkładamy zawartość dwóch rejestrów na stos (istotna jest kolejność &#8211; jeśli masz wątpliwości czemu pierwsza instrukcja odpowiada drugiem parametrowi, spójrz do <a href="http://www.sco.com/developers/devspecs/abi386-4.pdf">konwencji wołania</a>) tak, aby przekazać je do funkcji main, którą wołamy w linii 23. Znaczenie przekazanych parametrów omówię poniżej.</p>
<p>Spójrzmy teraz na kod jądra w C:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">char</span> hello<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;Hello from kernel!&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #339933;">*</span> mbd<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> magic<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> count <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>videoram <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #208080;">0xB8000</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* 0xB0000 for monochrome monitors */</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> magic <span style="color: #339933;">!=</span> <span style="color: #208080;">0x2BADB002</span> <span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #808080; font-style: italic;">/* something went wrong.. */</span>
		<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* .. so hang! :) */</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;">/* clear screen */</span>
	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">16000</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		videoram<span style="color: #009900;">&#91;</span>count<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'A'</span><span style="color: #339933;">;</span>
		videoram<span style="color: #009900;">&#91;</span>count<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #208080;">0x00</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* print black 'A' on black background */</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;">/* print string */</span>
	i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	count <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span>hello<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		videoram<span style="color: #009900;">&#91;</span>count<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> hello<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		videoram<span style="color: #009900;">&#91;</span>count<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #208080;">0x07</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* grey letters on black background */</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* just spin */</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Widzimy, że tym razem do funkcji main przekazane są dwa parametry, które włożyliśmy na stos. Pierwszy z nich to struktura informacyjna dostarczona przez bootloader, która zawiera informacje zarządane za pomocą flag. Druga, to kolejna wartość magiczna, infomująca nas o tym, czy wszystko poszło prawidłowo. Tym razem jest to 0x2BADB002. W liniach 41-45 widzimy bardzo prymitywną :) obsługę sytuacji błędnej. Reszta kodu jest taka, jak w odcinku poprzednim.</p>
<p>Co tak właściwie się stało? Specyfikacja Multiboot zapewnia nam że:</p>
<ul>
<li>rejestr EAX będzie zawierał magiczną wartość 0x2BADB002, jeśli jądro zostało prawidłowo załadowane (stąd wkładanie rejestru EAX na stos w pierwszym przedstawionym kodzie)</li>
<li>rejestr EBX będzie zawierał adres struktury informacyjnej z danymi zażądanymi we fladze (stąd wkładanie rejestru EBX na stos w pierwszym przedstawionym kodzie)</li>
<li><strong>linia A20 będzie aktywowana</strong></li>
<li><strong>rejestry segmentowe będą ustawione tak, aby realizowany był płaski model pamięci</strong></li>
<li><strong>będzie aktywowany tryb chroniony procesora</strong></li>
<li>bit 17 i 9 rejestru EFLAGS będzie zgaszony</li>
</ul>
<p>Jak widać, Multiboot Specification zapewnia nam wszystko, co poprzedni bootloader oraz sporo więcej. Więcej na temat struktur i gwarantowanego stanu <a href="http://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Specification">tutaj</a>.</p>
<p>Skrypt linkera pozostaje prawie bez zmian. Istotne jest, że tym razem musimy zdefiniować punkt wejściowy naszego programu (jądra), czyli etykietę loader oraz to, że możemy zażądać, aby nasz kernel został załadowany daleeeeeko za granicą 1MiB! Ja ładuję go zaraz za tą granicą:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">ENTRY (loader)
&nbsp;
SECTIONS {
    . = 0x00100000;
&nbsp;
    .text : {
        *(.text)
    }
&nbsp;
    .rodata ALIGN (0x1000) : {
        *(.rodata)
    }
&nbsp;
    .data ALIGN (0x1000) : {
        *(.data)
    }
&nbsp;
    .bss : {
        *(.bss)
    }
}</pre></div></div>

<p>Uważny czytelnik zauważy ustawienie wyrównań (polecenia ALIGN), które jednak aktualnie nie mają dużego znaczenia, więc nie będę ich omawiał.</p>
<p>Pozostała nam kompilacja do formatu elf w wariancie dla architektury i386 (x86):</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">nasm -f elf -o ./bin/loader.o loader.asm
gcc -o ./bin/main.o -c main.c -m32 -nostdlib -nostartfiles -nodefaultlibs
ld -melf_i386 -T linker.ld -o ./bin/kernel.bin ./bin/loader.o ./bin/main.o</pre></div></div>

<p>Oraz uruchamianie:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">qemu -kernel ./bin/kernel.bin</pre></div></div>

<p>Użycie QEMU może być zdziwieniem, gdyż nie używamy tu żadnego bootloadera typu GRUB. QEMU jednak, tak jak <a href="http://lukaszsowa.pl/qemu-podstawy/">wspominałem</a>, posiada wbudowany bootloader zgodny z Multiboot Specification. Włącza się go za pomocą przełącznika -kernel. Jeśli ktoś jednak bardzo chce <a href="http://wiki.osdev.org/Bare_bones">może użyć GRUBa</a>.</p>
<p>To tyle, nasz stuningowany kernel powinien działać.</p>
<h3>NIH</h3>
<p>Jestem zwolennikiem unikania syndromu <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">NIH</a>, stąd decyzja o użyciu dobrze napisanego i przetestowanego bootloadera zgodnego z Multiboot Specification. Stan naszej wiedzy nie ucierpiał na tej decyzji, gdyż mamy już za sobą napisanie prostego bootloadera :). W przyszłości będzie można do niego wrócić i wzbogacić go o ładowanie plików w formacie ELF i jeszcze kilka ficzerów. Na razie jednak, zajmijmy się tym co najważniejsze, czyli jądrem naszego systemu operacyjnego.</p>
<p>Tradycyjnie, pełen kod odcinka można pobrać tak:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">git clone git://github.com/luksow/OS.git --branch 0x05</pre></div></div>

<p>Lub obejrzeć go <a href="http://github.com/luksow/OS/tree/0x05">tu</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszsowa.pl/2010/11/tworzenie-systemu-operacyjnego-%e2%80%93-czesc-0%c3%9705-multiboot-specification/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

