Witam
Nie chciałem ożywiać tematu Budowa systemów opartych o jądro Linux więc założyłem nowy.
-
Gdzie znajdują się pliki nagłówkowe które należy dołączać do programu chcąc użyć funkcji linuksowych ?
Aby móc używać funkcji 'linuksowych' należy dołączyć pliki nagłówkowe (te których nam potrzeba) które znajdują się w:
/usr/include
Pytanie zadaje żeby zyskać pewność czy dobrze myślę/robię.
- Kiedy mamy biblioteki dynamiczne np. SFML to dlaczego czemu pliki *.so (odpowiedniki *.dll) maja dziwne nazwy ?
Na Windowsie jest dość prosto:
Na Linuxie zaś:
Pytanie: *Dlaczego na Linuksie mamy chociażby te dowiązania do plików .so ?
Znalazłem taka wzmiankę:
What's the point of this symlinks someone might ask? The purpose of this symlinks is that by adjusting those we can decide which version of library we want dynamic loader to find, as well as version of the library GNU Linker will find. This is up to us users but it is generally managed by the operating system so that when you upgrade libraries, their symlinks are automatically adjusted.
ale nie kupuje tego, nie rozumiem czemu na Windows da sie zrobić normalnie a na Linuxie jakies dowiązania dziwne.
3)Powiedzmy że mój program używa biblioteki współdzielonej w (Linuks *.so a w Windows *.dll)
Szeroko pojęty system ładuje bibliotekę do pamięci a następnie każdemu programowi udostępnia te raz już załadowaną bibliotekę.
3.1 - **Gdzie w pamięci znajduje się taka biblioteka ? ** Biblioteki dynamiczne sa ładowane pod jakieś adresy z danego zakresu czy też tam gdzie wolne miejsce jest?
3.2 - *Jaka część systemu (linuksowego) odpowiada za ładowanie biblioteki .so ?. Jest to część jądra czy też osobna aplikacja ? **
3.3 - Skąd aplikacja wie gdzie znajduję się funkcja - pod jakim adresem ? Na Windowsie (w .dll) jest coś takiego jak tablica importów. Znajdują się tam "nazwy" i powiązane z nazwami adresy - czy podobnie rzecz się ma z plikami .so?
4)Wywoływanie funkcji - co się wtedy dzieje? Jeżeli dobrze rozumiem to działa to mniej więcej tak:
- gdy w swojej aplikacji wywołuje funkcje
void displayFunnyCat(pointerToCat * _cat)
to za nazwę funkcji kompilator podczas kompilacji wstawia jej adres a wywołanie sprowadza się do przeskoczenia w inne miejsce i pobieranie instrukcji od tego miejsca ?
-
aby użyć funkcji z biblioteki dynamicznej pobieram adres żądanej procedury za pomocą funkcji która poszukuje w tablicy importów danej nazwy i zwraca powiązany z nią adres. Adres procedury jest zwracany (powiedzmy przypisuje go do wskaźnika) potem wywołuje funkcję, gdzie wywołanie sprowadza się do przeskoku procesora do miejsca w pamięci RAM gdzie jest załadowana funkcja biblioteczna a potem powrotu tam gdzie byłem ?
-
Kiedy mówimy o API np systemowym (np WInAPI) - **Jak działa wywołanie funkcji? **
a) Jest to skok pod "Adres Dobrze Znany" ? (Choć jak trochę pomyśleć to rozwiązanie ssie)
b) Jest do jakiegoś specjalnego rejestru procesora zapisywany numer żądanej funkcji ( np 44) a potem wywoływana jest specjalna instrukcja procesora która sprawdza jakiego system call'a zażądano i skacze pod adres tej procedury? (W między czasie tryb procesora jest zmieniany na bardziej 'uprzywilejowany', tak?)
Wydaje mi się że tak to mniej więcej działa (przynajmniej w Windows):
- Aplikacja woła funkcje przykładowo resetującą komputer - załóżmy że mamy uprawnienia
bool ExitWindowsEx( EWX_REBOOT, 0 );
- Powyższa funkcja analizuję argumenty - sprawdza uprawnienia - jeżeli je posiadamy wywoływana jest funkcja:
NTSTATUS NtShutdownSystem( ShutdownReboot )
- Funkcja ta ustawia w bliżej nieznanym rejestrze numer żądanego wywołania systemowego i dokonuje przerwania programowego (ang. Software interput)
- Wykonanie aplikacji jest wstrzymywane - wchodzimy w bardziej uprzywilejowany tryb procesora - ? ring 0 ?
- I skaczemy do odpowiednika funkcji NtShutdownSystem(ShutdownReboot ) w jadrze który zamyka system i wywołuje "BIOS Reset function"
- W między czasie powracamy do wykonania aplikacji i dajemy im czas aby zakończyć pracę.
Jeżeli chodzi o Linuksa znalazłem coś takiego:
That is to say, system calls are called by number, not by address as with a normal function call within your own program or to a function in a library linked to your program.
The inline assembly glue code I mentioned above uses this to make the transition from user to kernel space, taking your parameters along with it.
Skłaniam się więc ku opcji b) choć wątpię żebym dobrze ujął mechanizm działania wywołania funkcji API.
- Może trochę głupie pytanie ale **jak działają polecenia w Linuksie - chodzi o aplikacje takie jak mount? **
Oczywiście najpierw poszukałem informacji w sieci i zgodnie z tym czego się dowiedziałem ogólna zasada jest prosta - aplikacja pobiera argumenty - "pyta się " co chcemy zrobić - jaki system plików, gdzie zamontować i tak dalej a następnie wywołuje funkcje jądra - to bydle:
long sys_mount(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags,void __user *data);
Ten system call jest wywoływany z odpowiednimi parametrami i w ten sposób są montowane systemy plików.
Znalazłem w: https://github.com/torvalds/linux/blob/master/include/linux/syscalls.h
Dobrze piszę?
- Dlaczego w kodzie Linuxa znajdują się foldery takie jak security czy sound ?
security - This folder has the code for the security of the kernel. It is important to protect the kernel from computer viruses and hackers. Otherwise, the Linux system can be damaged. Kernel security will be discussed in a later article.
Może ktoś wyjasnić, z tego co zauwazyłem znajduja sie tam takie foldery jak AppArmor - wiki podaje:
AppArmor is a Linux kernel security module that allows the system administrator to restrict programs' capabilities with per-program profiles.
Rozumiem że w tym folderze znajduje się kod sterowników/ modułów które po załadowaniu lub wkompilowaniu w jadro udostepniaja funkcje które pozwalają podnieść bezpieczeństwo systemu operacyjnego ?
sound - This directory has sound driver code for sound/audio cards.
Rozumiem że Linux nie ma podsystemu dźwiękowego ale dostarcza posiada sterowniki kart dźwiękowych i dostarcza interfejs dla podsystemów takich jak
PulseAudio?
-
Czytając o bibliotekach dynamicznie ładowanych natrafiłem na pewną niezrozumiałą nazwę, mianowicie ABI:
Podaje cytat:
As I've already mentioned, full soname contains library name and major version of the library it represents. This is necessary because it is common practice that major version should be increased when ABI (Application binary interface) is broken.
Szukałem informacji czym jest ABI oraz czym rózni się od API.
API to wydaje mi się że jest to zbiór funkcji ,typów danych czy struktur które można wykorzystać w aplikacji.
Szukałem informacji o ABI - trochę poczytałem na Stackoverflow oraz Wikipedii ale zwyczajnie nie rozumiem.
ABIs are important when it comes to applications that use external libraries. If a program is built to use a particular library and that library is later updated, you don't want to have to re-compile that application (and from the end-user's standpoint, you may not have the source). If the updated library uses the same ABI, then your program will not need to change. The interface to the library (which is all your program really cares about) is the same even though the internal workings may have changed. Two versions of a library that have the same ABI are sometimes called "binary-compatible" since they have the same low-level interface (you should be able to replace the old version with the new one and not have any major problems).
Czy termin ABI ma związek np z konwencjami wywołania,przyjmowanymi argumentami (ich typem,ilością i kolejnością), zwracana wartością itp.?