Wiem, że po skompilowaniu kodu źródłowego, powiedzmy C ++, wyjściem kompilatora jest kod maszynowy (wykonywalny), który moim zdaniem był instrukcją bezpośrednio do procesora. Ostatnio czytałem o jądrach i dowiedziałem się, że programy nie mogą uzyskać bezpośredniego dostępu do sprzętu, ale muszą przejść przez jądro.
Kiedy więc skompilujemy jakiś prosty kod źródłowy, powiedzmy za pomocą tylko jednej printf()
funkcji, a kompilacja wygeneruje wykonywalny kod maszynowy, czy każda instrukcja w tym kodzie maszynowym zostanie wykonana bezpośrednio z pamięci (po załadowaniu kodu do pamięci przez system operacyjny) lub każde polecenie w kodzie maszynowym musi jeszcze przejść przez system operacyjny (jądro), aby zostać wykonane?
Przeczytałem podobne pytanie . Nie wyjaśnił, czy kod maszynowy generowany po kompilacji jest instrukcją bezpośrednio do procesora, czy też będzie musiał ponownie przejść przez jądro, aby utworzyć poprawną instrukcję dla procesora. To znaczy, co dzieje się po załadowaniu kodu maszynowego do pamięci? Czy przejdzie przez jądro, czy bezpośrednio porozmawia z procesorem?
źródło
printf
nie jest świetnym przykładem. Jest to wyraźnie zdefiniowane przez specyfikację C jako funkcja, która jest dostępna tylko w implementacjach „hostowanych” (co oznacza, że działa na jądrze, w przeciwieństwie do „wolnostojącego”, który może go nie wymagać). I na większości platform,printf
jest to po prostu funkcja zapewniana przez twoją,libc
która robi wiele rzeczy w twoim imieniu (która ostatecznie obejmuje połączenie systemowe do wydrukowania na standardowe wyjście). Naprawdę nie różni się niczym od dzwonienialibvlc_media_list_add_media
lubPyObject_GetAttr
, z tym wyjątkiem, że pewnaprintf
implementacja jest gwarantowana do połączenia bez dodawania dodatkowych niestandardowych-l
.Odpowiedzi:
Jako ktoś, kto napisał programy, które działają bez systemu operacyjnego, oferuję ostateczną odpowiedź.
To zależy od tego, jak ten program został napisany i zbudowany.
Możesz napisać program (zakładając, że masz wiedzę), który wcale nie wymaga systemu operacyjnego.
Taki program jest opisany jako samodzielny .
Programy ładujące i programy diagnostyczne są typowymi zastosowaniami dla samodzielnych programów.
Jednak typowy program napisany i wbudowany w niektóre środowisko systemu operacyjnego hosta domyślnie działałby w tym samym środowisku systemu operacyjnego hosta.
Aby napisać i zbudować samodzielny program, konieczne są bardzo wyraźne decyzje i działania.
Poprawny.
Jest to ograniczenie narzucone przez tryb procesora używany przez system operacyjny do uruchamiania programów i ułatwione przez niektóre narzędzia do budowania, takie jak kompilatory i biblioteki.
Nie jest to wewnętrzne ograniczenie każdego napisanego programu.
Każda instrukcja wykonywana jest przez CPU.
Instrukcja nieobsługiwana lub nielegalna (np. Proces ma niewystarczające uprawnienia) spowoduje natychmiastowy wyjątek, a procesor zamiast tego wykona procedurę obsługującą ten nietypowy warunek.
Funkcja printf () nie powinna być używana jako przykład „prostego kodu źródłowego” .
Tłumaczenie z obiektowego języka programowania wysokiego poziomu na kod maszynowy może nie być tak proste, jak sugerujesz.
Następnie wybierasz jedną z najbardziej złożonych funkcji z biblioteki wykonawczej, która wykonuje konwersje danych i operacje we / wy.
Pamiętaj, że twoje pytanie określa środowisko z systemem operacyjnym (i biblioteką wykonawczą).
Po uruchomieniu systemu i przejęciu kontroli nad komputerem przez system operacyjny nakładane są ograniczenia na to, co program może zrobić (np. Operacje we / wy muszą być wykonywane przez system operacyjny).
Jeśli spodziewasz się uruchomić samodzielny program (tj. Bez systemu operacyjnego), nie możesz uruchamiać komputera, aby uruchomić system operacyjny.
To zależy od środowiska.
W przypadku samodzielnego programu można go wykonać, tzn. Sterowanie jest przekazywane przez przeskakiwanie do adresu początkowego programu.
W przypadku programu ładowanego przez system operacyjny program musi być dynamicznie powiązany z bibliotekami współdzielonymi, od których jest zależny. System operacyjny musi utworzyć przestrzeń wykonywania dla procesu, który uruchomi program.
Kod maszynowy jest wykonywany przez CPU.
Nie „przechodzą przez jądro” , ale nie „rozmawiają z procesorem” .
Kod maszynowy (składający się z kodu operacyjnego i operandów) jest instrukcją dla procesora, która jest dekodowana i wykonywana jest operacja.
Być może następnym tematem, który powinieneś zbadać, są tryby procesora .
źródło
gcc -O2 -ffreestanding my_kernel.c special_sauce.S
aby plik wykonywalny nie zakładał, że będzie w nim normalna biblioteka lub system operacyjny. (Oczywiście można by się normalnie trzeba skrypt linkera, aby zmusić go do użytecznie połączyć w formacie pliku, który bootloader będzie chciał załadować!)Jądro to „tylko” więcej kodu. Po prostu ten kod jest warstwą, która żyje między najniższymi częściami systemu a rzeczywistym sprzętem.
Wszystko działa bezpośrednio na procesorze, wystarczy przejść przez kolejne warstwy, aby cokolwiek zrobić.
Twój program „potrzebuje” jądra w taki sam sposób, jak potrzebuje standardowych bibliotek C, aby móc korzystać z
printf
polecenia w pierwszej kolejności.Rzeczywisty kod twojego programu działa na CPU, ale gałęzie, które kod tworzy, aby wydrukować coś na ekranie, przechodzą przez kod
printf
funkcji C , przez różne inne systemy i interpretery, z których każdy wykonuje własne przetwarzanie, aby dowiedzieć się, jak to zrobićhello world!
faktycznie drukuje się na ekranie.Załóżmy, że masz program terminalowy uruchomiony na pulpicie menedżera okien, działający na twoim jądrze, które z kolei działa na twoim sprzęcie.
Dzieje się o wiele więcej, ale niech to będzie proste ...
hello world!
hello world!
na konsolihello world!
napisane na mnie, można umieścić go w pozycjix
,y
proszę?”Jest to ogromne uproszczenie wyłącznie w celu opisu. Oto smoki.
W rzeczywistości wszystko, co robisz, wymaga dostępu do sprzętu, czy to wyświetlania, bloków pamięci, bitów plików itp., Musi przejść przez jakiś sterownik urządzenia w jądrze, aby dokładnie ustalić , jak rozmawiać z odpowiednim urządzeniem. Czy to sterownik systemu plików na sterowniku kontrolera dysku twardego SATA, który sam siedzi na urządzeniu mostkowym PCIe.
Jądro wie, jak powiązać ze sobą wszystkie te urządzenia i oferuje stosunkowo prosty interfejs dla programów do robienia rzeczy bez konieczności posiadania wiedzy o tym, jak sami wszystkie te rzeczy robić.
Menedżery okien pulpitu zapewniają warstwę, która oznacza, że programy nie muszą wiedzieć, jak rysować okna i dobrze się bawić z innymi programami próbującymi wyświetlać rzeczy w tym samym czasie.
Wreszcie, program terminalowy oznacza, że twój program nie musi wiedzieć, jak narysować okno, ani jak rozmawiać ze sterownikiem karty graficznej jądra, ani całej złożoności związanej z obsługą buforów ekranu i timingu wyświetlania oraz faktycznym poruszaniem linie danych do wyświetlacza.
Wszystko jest obsługiwane przez warstwy po warstwach kodu.
źródło
To zależy od środowiska. Na wielu starszych (i prostszych!) Komputerach, takich jak IBM 1401, odpowiedź brzmiałaby „nie”. Twój kompilator i linker emitowały autonomiczny „plik binarny”, który działał bez żadnego systemu operacyjnego. Gdy Twój program przestał działać, załadowałeś inny, który również działał bez systemu operacyjnego.
System operacyjny jest potrzebny w nowoczesnych środowiskach, ponieważ nie uruchamiasz tylko jednego programu na raz. Udostępnianie rdzenia (rdzeni) procesora, pamięci RAM, urządzenia pamięci masowej, klawiatury, myszy i wyświetlacza wielu programom jednocześnie wymaga koordynacji. System operacyjny to zapewnia. Więc w nowoczesnym środowisku twój program nie może po prostu czytać i zapisywać dysku lub dysku SSD, musi poprosić system operacyjny, aby zrobił to w jego imieniu. System operacyjny otrzymuje takie żądania od wszystkich programów, które chcą uzyskać dostęp do urządzenia pamięci masowej, implementuje takie rzeczy, jak kontrola dostępu (nie może pozwolić zwykłym użytkownikom na zapisywanie plików systemu operacyjnego), umieszcza je w kolejce na urządzeniu i sortuje zwrócone informacje do właściwych programów (procesów).
Ponadto współczesne komputery (w odróżnieniu od, powiedzmy, 1401) obsługują połączenie bardzo szerokiej gamy urządzeń I / O, nie tylko tych, które IBM sprzedawałby w dawnych czasach. Twój kompilator i linker nie mogą wiedzieć o wszystkich możliwościach. Na przykład klawiatura może być podłączona za pomocą PS / 2 lub USB. System operacyjny pozwala instalować „sterowniki urządzeń” specyficzne dla urządzenia, które wiedzą, jak rozmawiać z tymi urządzeniami, ale zapewniają wspólny interfejs dla klasy urządzeń w systemie operacyjnym. Więc twój program, a nawet system operacyjny, nie musi robić nic innego, aby uzyskać naciśnięcia klawiszy z USB w porównaniu z klawiaturą PS / 2, lub w celu uzyskania dostępu, powiedzmy, do lokalnego dysku SATA vs. na NAS lub SAN. Te dane są obsługiwane przez sterowniki urządzeń dla różnych kontrolerów urządzeń.
W przypadku urządzeń pamięci masowej system operacyjny zapewnia na wszystkich sterownikach systemu plików, który oferuje ten sam interfejs katalogom i plikom, niezależnie od tego, gdzie i jak pamięć jest implementowana. I znowu, OS martwi się o kontrolę dostępu i serializację. Zasadniczo, na przykład, ten sam plik nie powinien być otwierany do zapisu przez więcej niż jeden program na raz bez przeskakiwania niektórych obręczy (ale jednoczesne odczyty są ogólnie ok).
Tak więc w nowoczesnym środowisku ogólnego zastosowania tak - naprawdę potrzebujesz systemu operacyjnego. Ale nawet dzisiaj istnieją komputery, takie jak kontrolery czasu rzeczywistego, które nie są wystarczająco skomplikowane, aby ich potrzebować.
Na przykład w środowisku Arduino tak naprawdę nie ma systemu operacyjnego. Jasne, jest mnóstwo kodu bibliotecznego, który środowisko kompilacji zawiera w każdym kompilowanym pliku binarnym. Ale ponieważ nie ma trwałości tego kodu między programami, nie jest to system operacyjny.
źródło
Myślę, że wiele odpowiedzi nie rozumie pytania, które sprowadza się do tego:
Zasadniczo CPU bezpośrednio wykonuje kod maszynowy . Byłoby znacznie wolniej, aby jądro wykonywało wszystkie aplikacje. Istnieje jednak kilka zastrzeżeń.
Gdy obecny jest system operacyjny, aplikacje zwykle nie mogą wykonywać niektórych instrukcji ani uzyskiwać dostępu do niektórych zasobów. Na przykład, jeśli aplikacja wykona instrukcję, która modyfikuje tablicę przerwań systemowych, procesor zamiast tego przeskoczy do procedury obsługi wyjątków systemu operacyjnego, tak że szkodliwa aplikacja zostanie zakończona. Ponadto aplikacje zwykle nie mogą odczytywać / zapisywać w pamięci urządzenia. (Tj. „Rozmawia ze sprzętem”). Dostęp do tych specjalnych obszarów pamięci polega na tym, jak system operacyjny komunikuje się z urządzeniami takimi jak karta graficzna, interfejs sieciowy, zegar systemowy itp.
Ograniczenia, jakie system operacyjny nakłada na aplikacje, są osiągane dzięki specjalnym funkcjom procesora, takim jak tryby uprawnień, ochrona pamięci i przerwania. Chociaż każdy procesor, który można znaleźć w smartfonie lub komputerze, ma te funkcje, niektóre procesory nie. Te procesory rzeczywiście potrzebują specjalnych jąder, które „interpretują” kod aplikacji, aby osiągnąć pożądane funkcje. Bardzo interesującym przykładem jest Gigatron , który jest komputerem z 8 instrukcjami, które można zbudować z układów, które emulują komputer z 34 instrukcjami.
Niektóre języki, takie jak Java, „kompilują się” do czegoś o nazwie Bytecode, co tak naprawdę nie jest kodem maszynowym. Chociaż w przeszłości interpretowano je w celu uruchamiania programów, obecnie zwykle używa się czegoś zwanego kompilacją Just-in-Time, więc kończą one bezpośrednio na procesorze jako kod maszynowy.
Uruchamianie oprogramowania na maszynie wirtualnej wymagało „interpretacji” kodu maszynowego przez program o nazwie Hypervisor . Ze względu na ogromne zapotrzebowanie branży na maszyny wirtualne producenci procesorów dodali do procesorów takie funkcje, jak VTx, aby umożliwić wykonywanie większości instrukcji systemu gościa bezpośrednio przez procesor. Jednak w przypadku uruchamiania oprogramowania zaprojektowanego dla niekompatybilnego procesora na maszynie wirtualnej (na przykład emulacji NES) kod maszynowy będzie wymagał interpretacji.
źródło
Podczas kompilowania kodu tworzony jest tak zwany kod „obiektowy”, który (w większości przypadków) zależy od bibliotek systemowych (
printf
na przykład), a następnie kod jest zawijany przez linker, który doda rodzaj programu ładującego program, który może być używany przez dany system operacyjny rozpoznaj (dlatego nie możesz na przykład uruchomić programu skompilowanego dla systemu Windows w systemie Linux) i umieć rozpakować kod i wykonać go. Więc twój program jest jak mięso wewnątrz kanapki i może być spożywany tylko jako pakiet, w całości.Cóż, to w połowie prawda; jeśli twój program jest sterownikiem trybu jądra, to tak naprawdę możesz uzyskać bezpośredni dostęp do sprzętu, jeśli wiesz, jak „rozmawiać” ze sprzętem, ale zwykle (szczególnie w przypadku nieudokumentowanego lub skomplikowanego sprzętu) ludzie używają sterowników, które są bibliotekami jądra. W ten sposób możesz znaleźć funkcje API, które potrafią rozmawiać ze sprzętem w sposób prawie czytelny dla człowieka, bez potrzeby znajomości adresów, rejestrów, czasu i wielu innych rzeczy.
Cóż, jądro jest jak kelnerka, której obowiązkiem jest odprowadzenie cię do stołu i podanie. Jedyne, czego nie może zrobić - to dla ciebie jeść, powinieneś to zrobić sam. Podobnie z twoim kodem, jądro rozpakuje twój program do pamięci i uruchomi twój kod, który jest kodem maszynowym wykonywanym bezpośrednio przez CPU. Jądro musi tylko cię nadzorować - co możesz robić, a czego nie wolno robić.
Kod maszynowy generowany po kompilacji jest instrukcją bezpośrednio do procesora. Bez wątpienia. Jedyną rzeczą, o której musisz pamiętać, nie cały kod w skompilowanym pliku to rzeczywisty kod komputera / procesora. Linker zawarł twój program w metadane, które tylko jądro może interpretować, jako wskazówkę - co zrobić z twoim programem.
Jeśli twój kod jest po prostu prostymi opcodes, takimi jak dodanie dwóch rejestrów, to zostanie on wykonany bezpośrednio przez CPU bez pomocy jądra, ale jeśli twój kod używa funkcji z bibliotek, wówczas takie połączenia będą wspomagane przez jądro, jak na przykład z kelnerką, jeśli chcesz do jedzenia w restauracji dadzą ci narzędzia - widelec, łyżkę (i to wciąż ich atuty), ale co z tym zrobisz, - to zależy od twojego „kodu”.
Cóż, tylko po to, by nie dopuścić do pojawienia się płomienia w komentarzach - mam nadzieję, że jest to model bardzo uproszczony, który pomógłby OP zrozumieć podstawowe rzeczy, ale mile widziane są dobre sugestie dotyczące poprawy tej odpowiedzi.
źródło
Zasadniczo tylko wywołania systemowe trafiają do jądra. Cokolwiek wspólnego z We / Wy lub alokacją / dezalokacją pamięci zazwyczaj kończy się wywołaniem systemowym. Niektóre instrukcje można wykonać tylko w trybie jądra i spowoduje to, że procesor uruchomi wyjątek. Wyjątki powodują przejście do trybu jądra i przejście do kodu jądra.
Jądro nie przetwarza wszystkich instrukcji w programie. Po prostu wykonuje wywołania systemowe i przełącza się między uruchomionymi programami w celu współużytkowania procesora.
Wykonanie alokacji pamięci w trybie użytkownika (bez jądra) nie jest możliwe, jeśli uzyskujesz dostęp do pamięci, nie masz uprawnień dostępu, MMU, wcześniej zaprogramowane przez jądro, zauważa i powoduje wyjątek „błąd segmentacji” na poziomie procesora , który uruchamia jądro, a jądro zabija program.
Wykonanie operacji we / wy w trybie użytkownika (bez jądra) nie jest możliwe, jeśli uzyskujesz dostęp do portów we / wy lub rejestrów urządzeń lub adresów podłączonych do urządzeń (jeden lub oba są potrzebne do wykonania dowolnego we / wy), wyzwalają one wyjątek w ten sam sposób.
Zależy od typu pliku wykonywalnego.
Jądra, oprócz pośredniczenia w dzielonym dostępie do pamięci RAM i sprzętu, pełnią również funkcję modułu ładującego.
Wiele „formatów plików wykonywalnych”, takich jak ELF lub PE, oprócz kodu zawiera metadane w pliku wykonywalnym i zadanie modułu ładującego do przetworzenia tego. Przeczytaj krwawe szczegóły dotyczące formatu PE Microsoft, aby uzyskać więcej informacji.
Te pliki wykonywalne również odwołują się do bibliotek ( pliki
.dll
obiektów współużytkowanych w systemie Windows lub Linux.so
) - należy podać ich kod.Jeśli Twój kompilator utworzy plik, który ma zostać przetworzony przez moduł ładujący systemu operacyjnego, a tego modułu ładującego nie ma, nie będzie działać.
Pewnie. Musisz przekonać system operacyjny, aby jakoś uruchomił surowy kod bez przetwarzania jakichkolwiek metadanych. Jeśli Twój kod wywołuje interfejsy API jądra, nadal nie będzie działać.
Jeśli w jakiś sposób załadujesz ten plik wykonywalny z systemu operacyjnego (tj. Jeśli pozwala on na załadowanie i wykonanie surowego kodu), nadal będzie w trybie użytkownika. Jeśli twój kod uzyskuje dostęp do rzeczy, które są zabronione w trybie użytkownika, w przeciwieństwie do trybu jądra, takich jak nieprzydzielona pamięć lub adresy / rejestry urządzeń I / O, zawiesi się z naruszeniem uprawnień lub segmentów (ponownie wyjątki przechodzą w tryb jądra i są obsługiwane tam) i nadal nie będzie działać.
Wtedy to zadziała.
źródło
TL; DR nr
Rozwój Arduino przychodzi na myśl jako obecne środowisko, w którym nie ma systemu operacyjnego. Zaufaj mi, na jednym z tych dzieci nie masz miejsca na system operacyjny.
Podobnie, gry dla Sega Genesis nie miały systemu operacyjnego dostarczonego przez Sega do wywołania. Właśnie stworzyłeś swoją grę w asemblerze 68K, pisząc bezpośrednio na goły metal.
Lub tam, gdzie obciąłem zęby, wykonując pracę wbudowaną w Intel 8051. Ponownie, gdy wszystko, co masz, to 2716 eprom o powierzchni 2k * 8, nie masz miejsca na system operacyjny.
Oczywiście zakłada to bardzo szerokie użycie słowa. Jako pytanie retoryczne warto zadać sobie pytanie, czy szkic Arduino jest aplikacją.
źródło
Chociaż nie chcę sugerować, że inne odpowiedzi nie są właściwe same w sobie, zawierają one zbyt wiele szczegółów, które, obawiam się, są dla ciebie bardzo niejasne.
Podstawowa odpowiedź jest taka, że kod zostanie wykonany bezpośrednio na procesorze. I nie, kod maszynowy nie będzie z nikim „rozmawiał”, jest na odwrót. Procesor jest aktywnym składnikiem i wszystko, co robisz na komputerze, zostanie wykonane przez ten procesor (nieco upraszczam, ale na razie jest OK). Procesor odczyta kod, wykona go i wypluje wyniki, kod maszynowy jest po prostu pokarmem dla procesora.
Twoje zamieszanie wynika z użycia słowa sprzęt. Chociaż podział nie jest tak wyraźny, jak kiedyś, lepiej jest myśleć o urządzeniach peryferyjnych niż po prostu nazywać wszystko sprzętem. Tak więc, jeśli na twoim komputerze jest system operacyjny lub podobny, twój program musi korzystać z jego usług w celu uzyskania dostępu do urządzeń peryferyjnych, ale sam procesor nie jest urządzeniem peryferyjnym, jest to główna jednostka przetwarzająca, na której program działa bezpośrednio.
Jądra, systemy operacyjne i podobne warstwy pośredniczące są zwykle używane tylko w większych systemach, w których oczekuje się, że uruchomi się kilka programów, i system musi zarządzać sposobem, w jaki te programy mogą korzystać z urządzeń peryferyjnych komputera (dość często na w tym samym czasie). W takich przypadkach uruchomione programy mogą uzyskiwać dostęp do tych urządzeń peryferyjnych tylko za pomocą systemu, który zdecyduje, jak je udostępnić i upewni się, że nie wystąpią konflikty. Małe systemy, w których nie ma potrzeby zarządzania między konkurującymi programami, ponieważ ich nie ma, często nie mają żadnego systemu bazowego, a pojedynczy program normalnie działający na tych systemach jest mniej lub bardziej wolny, aby robić wszystko, co chce z urządzeniami peryferyjnymi.
źródło
System BIOS, który działa na komputerze podczas uruchamiania, to kod wykonywalny przechowywany w pamięci ROM. Składa się z instrukcji maszyny i danych. Istnieje kompilator (lub asembler), który składa ten BIOS z kodu źródłowego. To jest szczególny przypadek.
Inne specjalne przypadki obejmują program ładujący ładujący jądro i samo jądro. Te specjalne przypadki są na ogół kodowane w języku innym niż C ++.
W ogólnym przypadku znacznie bardziej praktyczne jest, aby kompilator generował instrukcje wywołujące usługi systemowe dostarczane przez jądro lub procedury biblioteczne. Dzięki temu kompilator jest znacznie lżejszy. Sprawia również, że skompilowany kod jest mniejszy.
Na drugim końcu spektrum jest Java. W Javie kompilator nie tłumaczy kodu źródłowego na instrukcje maszynowe, jak zwykle rozumie się ten termin. Zamiast tego kod źródłowy jest tłumaczony na „instrukcje maszyny” dla wyobrażonej maszyny, zwanej Java Virtual Machine. Przed uruchomieniem programu Java należy go połączyć z środowiskiem wykonawczym Java, który zawiera interpreter wirtualnej maszyny Java.
źródło
W dawnych dobrych czasach twój program był odpowiedzialny za robienie wszystkiego, co trzeba było zrobić podczas wykonywania programu, albo robiąc to sam, albo dodając kod biblioteki napisany przez innych do twojego programu. Jedyną rzeczą, która działała obok tego na komputerze, był kod do odczytania w skompilowanym programie - jeśli miałeś szczęście. Niektóre komputery musiały mieć kod wprowadzony za pomocą przełączników, aby móc wykonać więcej (oryginalny proces „bootstrap”), lub nawet cały program wszedł w ten sposób.
Szybko okazało się, że miło jest mieć działający kod zdolny do ładowania i wykonywania programu. Później ustalono, że komputery były wystarczająco mocne, aby obsługiwać uruchamianie kilku programów jednocześnie, przełączając procesor między nimi, szczególnie jeśli sprzęt mógł pomóc, ale z dodatkową złożonością programów, które nie przyspieszały sobie nawzajem palców (na przykład , jak obsługiwać wiele programów próbujących jednocześnie wysłać dane do drukarki?).
Wszystko to spowodowało, że duża część kodu pomocnika została przeniesiona z poszczególnych programów do „systemu operacyjnego”, ze znormalizowanym sposobem wywoływania kodu pomocnika z programów użytkownika.
I tu jesteśmy dzisiaj. Twoje programy działają na pełnych obrotach, ale ilekroć potrzebują czegoś zarządzanego przez system operacyjny, wywołują procedury pomocnicze dostarczone przez system operacyjny, a ten kod nie jest potrzebny i nie jest obecny w samych programach użytkownika. Obejmowało to pisanie na wyświetlaczu, zapisywanie plików, dostęp do sieci itp.
Napisano mikrojądra, które zapewniają dokładnie to, co jest potrzebne do uruchomienia danego programu bez pełnego systemu operacyjnego. Ma to pewne zalety dla doświadczonych użytkowników, jednocześnie rozdając większość innych. Możesz przeczytać na ten temat stronę w Wikipedii - https://en.wikipedia.org/wiki/Microkernel - jeśli chcesz dowiedzieć się więcej.
Eksperymentowałem z Microkernelem zdolnym do uruchamiania wirtualnej maszyny Java, ale później odkryłem, że najlepszym miejscem do tego jest Docker.
źródło
W typowych systemach operacyjnych sam jądro jest plikiem wykonywalnym. (Windows ma
ntoskrnl.exe
; Linux mavmlinux
itp.) Jeśli potrzebujesz jądra, aby uruchomić plik wykonywalny, te systemy operacyjne nie mogą istnieć.Jądro potrzebujesz do robienia rzeczy, które robi jądro. Zezwalaj na uruchamianie wielu plików wykonywalnych jednocześnie, ocenianie między nimi, wyodrębnianie sprzętu itp. Większość programów nie jest w stanie samodzielnie wykonywać tych czynności w sposób kompetentny, a nie chciałbyś, aby to robiły, nawet gdyby mogły. W czasach DOS-a, który ledwo można nazwać samym systemem operacyjnym, gry często używały systemu operacyjnego jako niewiele więcej niż modułu ładującego i bezpośrednio uzyskiwały dostęp do sprzętu, podobnie jak jądro. Ale często musiałeś wiedzieć, jakie marki i modele sprzętu były w twojej maszynie, zanim kupiłeś grę. Wiele gier obsługiwało tylko niektóre rodziny kart wideo i dźwiękowych i działało bardzo źle na konkurencyjnych markach, jeśli w ogóle działały. Że'
źródło