Tworzenie oprogramowania w systemie Linusowym

1

Witam

Nie chciałem ożywiać tematu Budowa systemów opartych o jądro Linux więc założyłem nowy.

  1. 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ę.

  1. Kiedy mamy biblioteki dynamiczne np. SFML to dlaczego czemu pliki *.so (odpowiedniki *.dll) maja dziwne nazwy ?
    Na Windowsie jest dość prosto:
    windows_dlls.png
    Na Linuxie zaś:
    linux_dlls.png

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.

  1. 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ę?

  1. 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?

  1. 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.?

5

Na 1 pytanie odpowiedziałeś sobie dobrze ale tylko częściowo, pliki nagłówkowe znajdują się w /usr/include. Niekoniecznie muszą tam być same funkcje systemowe, trafiają tam też nagłówki z bibliotek instalowanych przez menadżer pakietów. Jeżeli manualnie instalowałeś jakąś bibliotekę, to nagłówki trafią do /usr/local/include.

  1. Biblioteki nie mają wcale dziwnych nazw. Biblioteki zawsze zaczynają się od słowa lib, potem jest nazwa biblioteki, rozszerzenie oraz wersja. Teraz z tymi linkami, to się robi aby zaoszczędzić miejsce na dysku. Bardzo wiele bibliotek stosuje tzw semantic versioning. Zasada jest taka, "fizyczny" plik zawsze musi mieć końcówkę w postaci x.y.z, następnie do tej biblioteki możesz linkować x.y oraz samo x. W systemie możesz mieć wiele dowolnych wersji mosquitto i dzięki takiemu zabiegowi nie musisz wymuszać na użytkowniku jakiejś konkretnej wersji (jeżeli nie potrzebujesz). Po co? Przykład:

W systemie masz bibliotekę libmosquitto.so.2.3.1 oraz dowiązania symboliczne do niej libmosquitto.so.2.3 oraz libmosquitto.so.2. Teraz tak, jeżeli Twój program zależy od mosquitto w wersji 2 i nic więcej Cie nie interesuje to linkujesz się z wersją 2, a dowiązanie to zawsze będzie wskazywać na najnowszą (jeżeli nikt ręcznie nic nie zmieniał) wersję mosquitto. Może jednak zdarzyć się, że będziesz mocno zależał od jakiejś wersji, np 2.3, wtedy linkujesz się pod mosquitto 2.3 i tyle. Jeżeli masz program, który wymaga mosquitto2 to będzie działać, program linkowany z wersją 2.4 już nie zadziała.

3.1 Biblioteka ładowana jest tam gdzie jest miejsce. Jak sama nazwa wskazuje są to biblioteki dynamiczne, nie mamy możliwości przewidzieć w kernelu ile tych bibliotek będzie w systemie załadowanych, aby przeznaczyć dla nich jakąś przestrzeń adresową.
3.2 Program ładujący program jak i biblioteki dzielone nazywa się  ld-linux.so.X gdzie X to wersja
3.3 procedure linkage table oraz global offset table. W programie, który korzysta z .so, adres funkcji to tylko offset (np call 0x120), później w runtimie przy pierwszym wywołaniu funkcji plt aktualizuje adres w got. Proponuję doczytać, bo ten mechanizm bardzo pobieżnie znam.

  1. No tak to właśnie działa, aby wywołać funkcję systemową w Linuksie, do rejestru rax zapisuje się numer funkcji do wywołania, w następnych rejestrach ładujemy parametry, a później wołamy funkcję syscall.

  2. Zależy od polecenie. Takie mount faktycznie korzysta z libmount i z wywołania kernela, ale polecenie grep już nie musisz korzystać z wywołań systemowych. Właściwie to w Linuksie nie ma jako tako poleceń. Każde polecenie to po prostu jakiś program, który może, a nie musi wywoływać jakichś ciężkich kernelowych funkcji.

  3. Kernel Linuksa posiada w sobie podsystem dźwiękowy, nazywa się on ALSA. W przeciwieństwie do Windowsa, gdzie sterowniki z reguły dostarcza producent, w Linuksie praktycznie wszystkie sterowniki są właśnie w kernelu (lub kompilowane jako modułu). PulseAudio to tylko serwer dźwięku, pod spodem wciąż pracuje ALSA, która to właśnie odtwarza i miksuje dźwięk. Kernel Linuksa posiada w sobie nawet prosty program memtest, który można odpalić poprzez bootloader.

  4. ABI to Application Binary Interface. Jak piszesz w C lub wyżej to Cię to nie interesuje za bardzo. ABI jest ważne dla ludzie klepiących w assemblerze. ABI definiujena przykład jak mają być zwracane wartości z funkcji. Jedno ABI powie, że wartość zwracana ma być zapisywana do rejestru rax, a inne zdefiniuje, że ma to być rbx.

Mam nadzieję, że żadnej gafy nie walnąłem. Jakby ktoś doszukał się nieprawidłowości to proszę mnie poprawić:)

1

Odnośnie mojego tematu "Budowa systemów operacyjnych opartych o jadro Linux"

Zadałem tam pytanie:

Jak to jest z plikami na Windowsie i GNU/Linuxie - chodzi mi o programowanie - na Windowsie linkuje *.a a program *.exe podczas działania ładuje *.dll Jak to jest z GNU/Linuxem i plikami *.so - czym są te pliki - pełnia te same funkcje co pliki dll czy (jeszcze) jakieś inne?

@Wibowit napisał:

  1. Z grubsza *.a to odpowiednik**1 *.exe (Endrju sugeruje *.lib), a *.so to odpowiednik *.dll. Na Linuksie jednak konwencja jest taka, że rozszerzenie .a się wywala z finalnej wersji programu i zostaje sama

A @Endrju dodał w komentarzu:

*.a to jest statyczna biblioteka ("a" od "archive", "archive" bo to "spakowana" kolekcja plików obiektowych *.o), odpowiednik *.lib w Windowsie. *.exe nie ma odpowiednika, bo pliki wykonywalne nie maja rozszerzenia. (Ogólnie rozszerzenia dla Linuksa są mało istotne, ale takie są tradycje)

============================
Poczytałem,dokształciłem się i połączyłem rozmaite fakty i choć nic odkrywczego tu nie napisze to zrobię takie małe podsumowanie - może komuś się przyda.

W systemach Linuksowych mamy biblioteki statyczne i dynamiczne.

Biblioteki statyczne są linkowane podczas kompilacji (w procesie konsolidacji) aplikacji i umieszczane w pliku wykonywalnym w ten sposób że gdy program będzie potrzebował / odwoływał kodu zmiennych czy typów danych zawartych w bibliotece będzie "miał je ze sobą" w pliku wykonywalnym.
Rozszerzenie biblioteki zależy od używanego kompilatora - w GNU GCC używa się plików z rozszerzeniem *.a - w kompilatorach firmy Microsoft są to rozszerzenia *.lib

Biblioteki dynamiczne w systemach Linuksowych maja rozszerzenie *.so (shared object) a w systemach Microsoft Windows *.dll
Załadowanie biblioteki dynamicznej następuje wtedy i tylko wtedy gdy:
a) [Na Linuksie ]aplikacja żąda dostępu do biblioteki współdzielonej za pomocą funkcji zadeklarowanych w pliku dlfcn.h [mówimy o języku C/C++]dołączanym do programu w ten sposób

#include <dlfcn.h>

b) Potrzebne biblioteki są zapisane w pliku wykonywalnym przez kompilator - w *.exe nazywa się to tablicom importów a plikach ELF to nie wiem gdzie dokładnie sorry - informacje te są umieszczane podczas kompilacji. System, nim uruchomi aplikację sprawdzi czy te biblioteki są dostępne jeżeli jakiejś zabraknie pojawi się błąd.

Plik *.o to rezultat asemblacji (tłumaczenia na kod maszynowy) danej jednostki kompilacji (na przykład pliku *.cpp i ewentualnie powiązanych z nim plików nagłówkowych - *.h *.hpp). Plik ten zawiera tylko kod maszynowy - brak w nim niezbędnych nagłówków w związku z czym nie nadaje się do uruchomienia, może zawierać również nierozwiązane symbole czyli (pre)deklaracje bez definicji.

Plik *.a jak wspomniałem jest to plik biblioteki statycznej używanej w kompilatorze GNU GCC - jak napisał @Endrju - plik *.a jest kolekcja plików *.o .
EDIT
Zapomniałem wspomnieć że
**1 - Pliki *.a nie są typem plików wykonywalnych na Linuxie, aby plik był wykonywalny musi być właściwie zbudowany - zobacz ELF - nagłówki,sekcje itp oraz mieć nadane prawa do wykonania - na Linuksie rozszerzenie nie ma znaczenia - możesz wykonać plik microVirus.png byle był zbudowany właściwie i miał nadane prawo do wykonania.

Jednakże pewna rzecz mi się tutaj nie zgadza.
@mlyszczek - jak to możliwe że linker bibliotek dynamicznych (ten program co ładuje pliki *.so) sam ma rozszerzenie ld.so - myślałem że w Linuksach *.so to tylko i wyłącznie biblioteki dynamiczne.

1
  1. Gdzie znajdują się pliki nagłówkowe które należy dołączać do programu chcąc użyć funkcji linuksowych

Nieistotne. Robisz #include <cośtam.h> i działa. Kompilator wie gdzie szukać.

  1. Kiedy mamy biblioteki dynamiczne np. SFML to dlaczego czemu pliki *.so (odpowiedniki *.dll) maja dziwne nazwy

Bo tak. Decyzja projektowa dokonana wiele lat temu. Pewnie jeszcze Linuksa wtedy nie było.

Gdzie w pamięci znajduje się taka biblioteka

Gdzieś, to nieistotne z punktu widzenia programisty. I może się to zmieniać z wersji systemu na wersję...

Dlaczego w kodzie Linuxa znajdują się foldery takie jak security czy sound

Boo... ktoś tak wymyślił?

3

Masz rację, bo ld.so w istocie jest biblioteką dynamiczną... tylko z mainem w środku;) Mały przykład aby przetworzyć to:

// lib.c
#include <stdio.h>

void foo(void)
{
        printf("%s(%s):%d\n", __func__, __FILE__, __LINE__);
}

int main(void)
{
        printf("%s(%s):%d\n", __func__, __FILE__, __LINE__);
        foo();
        return 0;
} 
// main.c
#include <stdio.h>

extern void foo(void);

int main(void)
{
        printf("%s(%s):%d\n", __func__, __FILE__, __LINE__);
        foo();
        return 0;
}
$ gcc -fPIC -pie -o lib.so lib.c -Wl,-E
$ gcc main.c ./lib.so
$ ./lib.so 
main(lib.c):11
foo(lib.c):6
$ ./a.out 
main(main.c):8
foo(lib.c):6
0
  1. API - Application Programming Interface - wikibooks podaje:

An API encompasses all the function calls that an application program can communicate with the hardware or the operating system, or **any other application that provides a set of interfaces to the programmer **(i.e.: a library), as well as definitions of associated data types and structures.

8.1)
Możecie mi wyjaśnić jak działa ta komunikacja z inna aplikacją która udostępnia zbiór interfejsów programiście ? - możecie mi wyjaśnić o komunikacji jakiego typu mówimy, jak on się odbywa i tak dalej ? W swoim ostatnim temacie o Linuksie - "Budowa systemów operacyjnych opartych o jądro Linux" zadałem pytanie o działanie PAM (Pluggable Authentication Modules ) - na stronie głównej czytamy:
Basically, it is a flexible mechanism for authenticating users. [...]
PAM provides a way to develop programs that are independent of authentication scheme. These programs need "authentication modules" to be attatched to them at run-time in order to work. Which authentication module is to be attatched is dependent upon the local system setup and is at the discretion of the local system administrator.

Po dziś dzień próbuje zrozumieć jak to działa - a czytałem polecone linki nawet kilka razy - co mnie teraz interesuje - PAM udostępnia interfejs - zbiór funkcji o którym wspomniałem:

PAM udostępnia interfejs programistyczny - API do komunikacji z menadżerem
Oto przykład aplikacji używającej PAM: http://www.linux-pam.org/Linux-PAM-html/adg-example.html
Nie za bardzo, mimo 'analizy' kodu powyższej aplikacji rozumiem proces uwierzytelniania.

Widocznie za słabo rozumiem czym jest API gdyż jak wynika z wspomnianej "analizy" prosty program uzywa następujących funkcji (wywoływane są w tej kolejności):

int pam_start( service_name,user,pam_conversation, pamh) - The pam_start function creates the PAM context and initiates the PAM transaction
int pam_authenticate(pamh,flags); - The pam_authenticate function is used to authenticate the user.
int pam_acct_mgmt(pamh, flags); -** The pam_acct_mgmt function is used to determine if the users account is valid.**
int pam_end(pamh,pam_status); - The pam_end function terminates the PAM transaction and is the last function an application should call in the PAM context.

W linkach które otrzymałem dowiedziałem się że jest to super hiper mega moduł bez którego życie jest niemożliwe ( :) ), odpowiada on za autentykacje (jak wskazał @vpiotr - sprawdzenie tożsamości użytkownika)
Chodzi mi o to jak te funkcje działają:
a) ** Czy za pomocą tego API program komunikuje się z działającym procesem - czy jest to forma IPC ?** Proces dokonuje sprawdzenia np hasła i uruchamia w kontekście żądanego użytkownika ?
b) Wywołuje "sztywne funkcję" -dokonuje ona autoryzacji i zwraca kod błędu ? ** Jeżeli mamy sukces to program sam się uruchamia w kontekście roota tfu żądanego użytkownika ;)

8.2) Kiedy pisałem:

OK Przeczytałem już parę artykułów o PAM ale wciąż nie rozumiem jak przebiega uwierzytelnianie użytkownika

Chodziło mi o to że nie wiem :
a)jak się konfiguruję PAM - dzięki za linki - przeczytałem ale dla mnie dalej mało to intuicyjne.
b)jak przebiega uwierzytelnianie oraz dlaczego w ten sposób

! Niepotwierdzone !
Jak na razie WYDAJĘ MI SIĘ że PAM działa jako root - proces próbuje się uwierzytelnić jako kacper, podaje hasło i wszelkie niezbędne dane, PAM stwierdza po sprawdzeniu podanego hasła (wiem że PAM obsługuje jeszcze inne sposoby autoryzacji/uwierzytelniania) oraz sprawdzeniu co mówi konfiguracja PAM postanawia przychylić się do żądania procesu.
Za pomocą setuid(),setguid() lub podobnej funkcji zmienia UID,GUID procesu co sprawia że kernel uznaje proces za działający w "kontekście" tego użytkownika.
Tak to działa, co(ś) źle napisałem ?

9)Jak wygląda sprawa z rootem na Linuksach?
Konto root to domyślnie konto o najwyższych przywilejach - z czego one wynikają - czy z tego że każdy ważny plik systemowy należy do roota czy też z tego że root ma UID 0 i w kernelu jest "napisane" - kto ma UID 0 ma władzę ? ;)

0

Brian Ward "Jak działa linux. Podręcznik administratora. Wydanie II" - Strona 217.
Masz tam łagodny wstęp do tego czego szukasz na temat PAM.

0

Dziękuje za odpowiedzi - co się tyczy mojego pytania o API - cóż myślę że poprosiłem was o wytłumaczenie na zbyt skomplikowanym przykładzie - ten PAM jest zbyt skomplikowany na potrzeby mojego pytania. W poprzednim poście napisałem że wikibooks podaje:

An API encompasses all the function calls that an application program can communicate with the hardware or the operating system, or any other application that provides a set of interfaces to the programmer (i.e.: a library), as well as definitions of associated data types and structures.

Możecie mi wyjaśnić jak działa ta komunikacja z inna aplikacją która udostępnia zbiór interfejsów programiście ? - możecie mi wyjaśnić o komunikacji jakiego typu mówimy, jak on się odbywa i tak dalej ?

8.3 Czy możecie mi wytłumaczyć czym jest API - powiedzmy że potrzebuję załadować biblioteke dynamiczną podczas działania programu.
Ładowaniem bibliotek zajmuje się linker dynamiczny czyli aplikacja (tak właściwie biblioteka z funkcja główną) ld.so (u mnie nazwa trochę inna ale to jakieś względy kompatybilności z czymś tam ...)
Aby to zrobić użyje funkcji dlopen zadeklarowanej w pliku <dlfcn.h> - na przykład:

dlopen ("MyDynamicLib.so", RTLD_LAZY);

Z cała pewnością używam tutaj API ale teraz mam wątpliwości:
a) czy wywołując funkcję dlopen(arg,arg) ja wywołuje zwyczajnie funkcje zawartą w bibliotece - z tymże ta funkcja jest wywoływana i wykonywana przez mój proces. Jeżeli ta opcja jest prawdziwa to rozumiem że skorzystałem z funkcji udostępnianej przez ld.so i wtedy wszystko jest dla mnie jasne*.
b) czy wywołując funkcję dlopen(arg,arg) zlecam załadowanie biblioteki procesowi który jest aktywny w tle. Tutaj docohdzi do komunikacji - mój proces mowi innemu żeby załadował bibliotekę - ale wtedy to powinno być IPC a nie API, chyba ...

    • Powtórzę: o jakiego rodzaju komunikacji mówimy gdy korzystam z API.
1

Jak odwołujesz się do API ładując na przykład kod libki, to ten kod wywołuje się z uprawnieniami aplikacji, która ten kod wywołuje. Dopiero później, w libce może być kod, który komunikuje się z innym procesem na innych uprawnieniach. Przykład:

Mam sobie w systemie proces my_kill, który pozwala na ubijanie niektórych procesów roota z poziomu zwykłego użytkownika. Tworzę bibliotekę, która ma funkcję mkill(pid_t). Teraz tworzę program, który linkuje się z tą bibliotekę i woła on funkcję mkill(pid). Teraz funkcje mkill przekazuje moje żądanie do procesu my_kill, na przykład poprzez /dev/mqueue/my_kill albo dowolny inny mechanizm komunikacji między procesami.

Przy API ciężko mówić o jednym rodzaju komunikacji, bo API to generyczna nazwa na komunikację między dwoma kawałkami kodu. I tak, API to może być na przykład zestaw funkcji, albo zestaw przyjmowanych ramek TCP, albo zestaw prostych ramek do komunikacji po RS232, albo IPC jak kolejki czy semafory.

Mam nadzieję, że jasno wytłumaczyłem o co chodzi:)

0

Dzięki za odpowiedzi

@mlyszczek
Dałeś interesujący przykład komunikacji IPC za pomocą biblioteki - dzięki
Poczytałem - API to nie (jak sądziłem) tylko funkcję w bibliotece zewnętrznej (np WinAPI,SFML etc).

1) What is an API?
API is a contract. A promise to perform described services when asked in specific ways.
2) How is it used?
According to the rules specified in the contract. The whole point of an API is to define how it's used.
3) When and where is it used?
It's used when 2 or more separate systems need to work together to achieve something they can't do alone.

Przykład
Aplikacja "Pogoda"
Bez API:
*Weather application must open weather.com site and read the details as human does. *
Za pomocą API:
Weather application will send a message to weather.com and receives the result and then display it.

Przy API ciężko mówić o jednym rodzaju komunikacji, bo API to generyczna nazwa na komunikację[+] między dwoma kawałkami kodu. I tak, API to może być na przykład zestaw funkcji, albo zestaw przyjmowanych ramek TCP, albo zestaw prostych ramek do komunikacji po RS232, albo IPC jak kolejki czy semafory.

Tak więc API :

[API] is the way for an application to interact with certain system/application/library/etc.
For example, there are API's for OS (WinAPI), API's for other applications (like databases) and for specific libraries (for example, image processing), etc.
APIs are usually developed in a form consumable by a client application.** For C/C++ applications, it a set header files and dynamic/static libraries. **For Java - set of jars. And so on.

+
Zależnie od dziedziny mianem API określimy m.in
0)The x86 (IA-32) Instruction Set (ponoć użyteczne ;-) )
1)A BIOS interrupt call
2)OpenGL which is often exposed as a C library
3)Core Windows system calls: WinAPI
4)The Classes and Methods in Ruby's core library
5)The Document Object Model exposed by browsers to JavaScript
6)Web services, such as those provided by Facebook's Graph API
7)An implementation of a protocol such as JNI in Java

Zgodnie z tym czego się dowiedziałem.

  1. Czy znacie jakieś aplikację na Linuksa z dostępem do kodu źródłowego które wypalają obraz systemu na pendrive czyniąc nośnik botowalnym?
    Ja znam Rufusa - ale okazało się że on jest w WinAPI robiony :(

EDIT: Przypomniałem sobie o aplikacji z dystrybucji Deepin.
Deepin Boot Maker - jest to aplikacja do tworzenia bootowalnych nośników - jest napisana w C++, używa biblioteki QT - w tym QT to można chyba wszystko ;)
https://github.com/linuxdeepin/deepin-boot-maker
Znacie może jakieś inne?

  1. Mam małą sieczkę w głowie jeżeli mowa o bibliotekach na Linuksie.
    Chodzi mi o np glibc,syscall'e i tak dalej.

O ile jestem w stanie zrozumieć sens bibliotek do otwierania plików multimedialnych np ffmepg tak nie rozumiem dlaczego społeczność GNU rozwija bibliotekę GNU lib c
Jedyne powody jakie mi przychodzą do głowy to:

  • przykrycie sycall'i poszczególnego jądra (GNU rozwija jadro ?Hurd?)
  • standaryzacja - zgodność z normami czy tam udostępnienie wspólnego API dla aplikacji pisanych w C
  • nie wiem jak to określić - ?stabilizacja? API

*A system call is a special function/command that a program uses to communicate with the kernel of the operating system. *

10.1 A system call is a special function/command that a program uses to communicate with the kernel of the operating system. *
Czy zaleca się nie używanie (bezpośrednio) wywołań systemowych a jeżeli tak dlaczego? Czy działanie,przyjmowane argumenty oraz dostępność poszczególnych syscall'i może sie zmieniać?
10.2
* Czy ktoś kiedyś używał glibc ? Czy QT jest nakładką na m.in glibc, bibliotekę od X11 czy waylanda ?**
10.3 Kiedy używam glibc a kiedy (nie wiem czy dobrze to określam) funkcji jądra czy jego API?
10.4 **Gdzie znajdują się biblioteki .so czy .a glibc - te które zawierają kod i są używane przez aplikację ?
10.5 Czy dobrze myślę że ostatecznie do rzeczy takich jak system plików czy wątki glibc używa syscall'i jadra (Linux/Hurd).

0
  1. Na Linuksie bootowalne obrazy robi się za pomocą isohybrid, a potem na pendrive wrzuca za pomocą dd

  2. glibc po prostu zawiera dodatkowe funkcje (np posix, czy funkcje pomagające w rozwijaniu oprogramowania gnu), których nie ma w standardowej bibliotece.
    10.1 syscalle po to są udostępnione, żeby z nich korzystać, i nie trzeba się tego bać. Jakbyś chciał otworzyć urządzenie do odczytu/zapisu bez funkcji systemowej open? Nie ogarniesz.
    10.2 Czy nakładka to dobre słowo... hmm... Niby można tak to nazwać. QT jest biblioteką opakowującą biblioteki występujące w różnych systemach, aby program napisany w QT mógł działać na wielu systemach operacyjnych. I tak, na Linuksie QT korzysta z X11 lub Wayland do rysowania okien, a na Windowsie z kolei QT będzie korzystać windowsowych funkcji rysujących okna.
    10.3 Zwykle wywołania systemowe są w bibliotece c (glibc) i dopiero glibc woła syscall. glibc działa tutaj jako taki wrapper.
    10.4 Zależy od dystrybucji. Z reguły albo /usr/lib albo /lib albo /lib64, może też być w /usr/local/lib jak sami instalowaliśmy libkę.
    10.5 patrz 10.3

0

Dzięki za odpowiedź !

  1. glibc po prostu zawiera dodatkowe funkcje (np posix, czy funkcje pomagające w rozwijaniu oprogramowania gnu), których nie ma w standardowej bibliotece.

OK, rozumiem że w Linuxie syscall'e umożliwiają prace z plikami,operacje związane z datą i godziną ale Linux nie udostępnia nam na przykład funkcji matematycznych.

10.3 Zwykle wywołania systemowe są w bibliotece c (glibc) i dopiero glibc woła syscall. glibc działa tutaj jako taki wrapper.

Czyli podobnie jak WinAPI? Wywołujemy Windowsową funkcje CreateFile(args) ona sprawdza argumenty które podaliśmy, jeżeli są poprawne wywołuje syscall NtCreateFile(args).
Czy podobnie działa to na Linuxie, dobrze myślę?

Nie rozumiem jeszcze jednej rzeczy jeżeli mówimy o bibliotece standardowej języka C od społeczności GNU.
Z tego co się dowiedziałem, istnieje kilka implementacji biblioteki standardowej C - zresztą tak jest ze wszystkim na tym Linuksie ;)

10.6)Jak mogę zmienić używaną w mojej aplikację bibliotekę standardową - np na diet libc
Czy wystarczy zmienić pliki nagłówkowe na te które zawiera biblioteka?

10.8) Każdą bibliotekę którą chcemy mieć dołączoną do programu musimy skonsolidować z aplikacją - za pomocą opcji trzeba powiadomić kompilator by "wszył" w plik wykonywalny bibliotekę (*.a) lub informację jaka biblioteka jest potrzebna ( *.so )? **Dlaczego nie muszę podobnie robić jeżeli chodzi o bibliotekę standardową - tylko pliki nagłówkowe i już - kompilator wie co robić, co linkować - skąd kompilator wie jaki plik .so lub .a powiązać z programem?

10.7) Jeżeli chodzi o WinAPI - ono też nie udostępnia m.in funkcji matematycznych.
Czy jest tak jak piszę?
Kiedy wywołuje funkcję z WinAPI mój program skacze do miejsca w pamięci gdzie jest załadowana biblioteka ?kernel32.dll? ale kiedy wywołuję funkcję matematyczne moja aplikacja skacze do kodu biblioteki zawierającej funkcję matematyczne - np libstdc++.dll ? - (Na Windowsie jest biblioteka *.dll o nazwie takiej lub podobnej - ta biblioteka jest dostarczana z kompilatorem).
W pliku wykonywalnym i ELF i EXE zawarte są informację jakich bibliotek ( a może nawet i jakich funkcji) oraz jakiej wersji każdej z bibliotek wymaga aplikacja do działania?

0

9)Jak wygląda sprawa z rootem na Linuksach?
Konto root to domyślnie konto o najwyższych przywilejach - z czego one wynikają - czy z tego że każdy ważny plik systemowy należy do roota czy też z tego że root ma UID 0 i w kernelu jest "napisane" - kto ma UID 0 ma władzę ? ;)

Spróbuje sam sobie odpowiedzieć.
Zgodnie z tym czego się dowiedziałem ....
Konto root ma domyślnie najwyższe uprawnienia w systemie lecz nie wynikają one z nazwy "root" lub identyfikatora użytkownika 0[1].
Potęga konta roota wynika raczej z tego że jest on właścicielem wszystkich plików systemowych - tych zwartych w głównym katalogu - root
directory. Właśnie dlatego potrzeba roota by przykładowo zainstalować oprogramowanie - aby zmodyfikować pliki/katalogi systemowe musisz działać jako ich właściciel.
Nie dostrzegam jednak przeszkody w tym żeby na przykład ustawić konto "kacper" jako właściciela wszystkich plików co de facto dało by mi prawa roota :)

1 - Możliwe że w kodzie jądra - w Linuksie jest napisane coś w stylu:

if( current_user->uid == 0)ALLOW_FOR_OPERATION
else check_privilege_of_user();
 

nie bez powodu w wielu poradnikach jest napisane : " Root always has a UID of zero. " -** możliwe że dla roota UID 0 zostało jakby zarezerowane - a może to tylko tradycja - nie wiem tego :( .**

  1. Czym jest pakiet oprogramowania?
    **Czy pakiet to archiwum podobne do *.tar.gz czy .zip czy .rar ?
    *Z tym zastrzeżeniem że musi być odpowiednio zbudowany - zawierać (dla pakietów .deb) pliki?

Przykładowo:

data.tar.gz
control.tar.gz
debian-binary

Więcej tu:
http://www.tldp.org/HOWTO/html_single/Debian-Binary-Package-Building-HOWTO/#AEN66
Debian Binary Package Building HOWTO
**
Czy w jednym pakiecie może być więcej niż jedne program - plik wykonywalny?**

Common UNIX Printing System to "serce" linuksowego systemu drukowania we współczesnych dystrybucjach Linuksa. Składają się na niego m.in. pakiety cups, gimp-print-cups, libgnome-cups oraz w niektórych systemach cups-drivers.

jeżeli tak to dlaczego np. taki CUPS został podzielony na tyle osobnych pakietów?

CUPS to jednak znacznie więcej niż tradycyjny spooler. To również biblioteki systemowe, dzięki którym wszystkie aplikacje mają dostęp do drukarek oraz możliwość konfiguracji sposobu druku.

Myślałem ze dostęp do sprzętu zapewnia Linux(kernel) - dlaczego potrzeba do tego specjalnego programu/bibliotek?

Oczywiście znam mniej/wiecej mechanizm wydruku:

...gdy ostatecznie wydamy komendę Drukuj, nasza aplikacja przesyła do CUPS albo gotowy plik postscriptowy, albo surowe dane, np. plik tekstowy. W tym drugim przypadku CUPS wpierw uruchamia specjalny program pomocniczy, który konwertuje nasz tekst na format PostScript. Tak więc, niezależnie od tego, co drukujemy, ani jaką posiadamy drukarkę, nasz system wygeneruje plik PostScript. Zawiera on uniwersalny język opisu strony.

ale zastanawia mnie dlaczego nie zajmuje się tym kernel lub sterownik tylko osobny program.

  1. Gdzie są instalowane aplikację?
    Właściwie to w podanym linku jest napisane:

** The 'data.tar.gz' file contains all the files that will be installed with their destination paths:**

Jednak zastanawia mnie** dlaczego nie wydzielono na aplikację specjalnego folderu** - coś pdobnego do *Program Files *w systemach M$.
Co jest powodem że lepiej zaśmiecać katalogi systemowe?

1

Do linuksowego gurusa mi daleko, ale po paru latach użytkowania systemu coś tam wiem.

  1. root tak, jest specjalnym użytkownikiem i jego UID to 0. Przepięcie wszystkich plików na innego użytkownika nie da Ci praw roota, ponieważ, jak odgadłeś, w wielu miejscach sprawdzane jest UID użyszkodnika. Nie tylko kernel, ale programy też często mogą patrzeć na UID - choć tu często bywa w drugą stronę: program nie pozwala uruchomić się z roota, jako zabezpieczenie na wypadek, gdyby jakaś podatność pozwalała przejąć kontrolę nad programem. Jako root możesz zniszczyć system, jako httpdaemon co najwyżej podmienisz stronę domową.
    Z reguły, jeśli już, sprowadza się to do:
if(!getuid()) { /* nie root - coś trza zrobić */ }

  1. Nie wiem, jak .deb, .rpm to tak naprawdę .zip + trochę metadanych (np. architektura paczki, zależności, et cetera). Instalacja, w dużym skrócie, sprowadza się do rozpakowania rzeczonej zipki w roocie (w sensie /) i ew. uruchomienia sriptletów.
    Jaki jest sens dzielenia oprogramowania na większą liczbę pakietów?
  • rozdział części często się zmieniającej od rzadko się zmieniającej - dotyczy głównie gier. Assety są dostępne jako paczka funnygame-data, sama gra jako funnygame. Dzięki temu, jak wyjdzie nowy patch, nie musisz ściągać znowu 1GiB modeli i tekstur, tylko łapiesz 15MiB paczkę z plikiem wykonywalnym i po sprawie.
  • rozdział części uniwersalnych od specyficznych dla architektury - o ile ELFy muszą być kompilowane osobno na każdą architekturę, o tyle paczki typu assety, configi, dokumentacja, mogą być używane bez problemu na wszystkich architekturach. Wydzielając te pliki do osobnej paczki, nie musisz hostować pinć razy tego samego, tylko z inną naklejką (x86/amd64/ppc i tak dalej).
  • odzwierciedlenie modularności programu - jeśli program w oryginale składa się z "bazy", do której dorzuca się pluginy, to pakowanie wszystkiego w jedną paczkę po pierwsze zmusza użytkowników do podążania twoją wizją (może komuś pluginy niepotrzebne, a ty go zmuszasz do trzymania iluśtam mebibajtów), po drugie powoduje, że za każdym razem, jak w pluginie się coś zmienia, użytkownik pobiera cały program od nowa (patrz punkt pierwszy).
  • paczki pod specyficzny hardware - np. sterowniki do kart graficznych. Nie możesz przewidzieć, jaki hardware ma użytkownik, więc przy świeżej instalacji systemu ładujesz wszystkie sterowniki... ale dzięki temu, że są rozdzielone na paczki, może on sobie potem odinstalować, czego nie potrzebuje.
  1. Aplikacje instalowane są w /usr/bin, biblioteki w /usr/lib (lub lib64), pliki typu wspomniane assety w /usr/share, konfiguracje systemowe w /etc. Oprogramowanie "niepaczkowane" często wrzuca się w /opt.
    Zwróć uwagę, że paczki z reguły mogą być instalowane tylko przez roota. Wszelkie graficzne menadżery paczek zazwyczaj w chwili instalacji pytają o hasło i lecą wtedy na sudo, bądź korzystają z jakiegoś demona na prawach roota, który instaluje paczki w ich imieniu. Stąd też, ma sens paczki trzymać w folderach systemowych - w końcu zainstalowane programy są dostępne dla wszystkich użytkowników. Jak ktoś chce mieć coś na własny użytek, to trzyma to $HOME i się stamtąd nie wychyla.
0

Deb jest nieco bardziej inteligentnie zbudowany niż rpm, rpm to może być w najprostszym przypadku tylko zip z plikami w środku i też przejdzie. Tu więcej informacji o deb: https://pl.m.wikipedia.org/wiki/Deb

nie musisz hostować pinć razy tego samego, tylko z inną naklejką (x86/amd64/ppc i tak dalej).

Nie. Takie pakiety są oznaczone jako niezależne od architektury (all) a nie z żadną naklejką

0
Zibiiiii napisał(a):

Nie. Takie pakiety są oznaczone jako niezależne od architektury (all) a nie z żadną naklejką

Ale mi właśnie o to chodziło - jak wydzielisz assety/konfigi/dokumentacji do osobnej paczki, to zamiast program+rzeczy[x86], program+rzeczy[amd64], et cetera, trzymasz rzeczy[noarch] i samprogram[x64], samprogram[amd64]. :)

0

Wiem że to głupie ale o jaką architekture chodzi - oznaczamy czy aplikacja jest 32/64 bit czy też oznaczamy wymganaia sprzętowe?

1

Architektura, czyli w dużym skrócie - oznaczamy, czy aplikacja jest 32bit, czy 64bit.

W mniejszym skrócie - procesor to (ponownie, uproszczenie) maszyna licząca, której wydaje się rozkazy. Rozkazy muszą mieć określony format. W swoim lapku/wieży masz najprawdopodobniej procesor, który rozmawia systemem amd64, który z kolei jest 64-bitowym rozwinięciem systemu x86 (dlatego można na 64-bit systemach uruchamiać 32-bit aplikacje). Oprócz tego jest jeszcze cała masa innych architektur, jak np. ARM (prawie wszystkie telefony, większość tabletów, niektóre laptopy (Chromebooki zwłaszcza)), MIPS (dużo urządzeń typu routery), PowerPC (do 2006 roku wszystkie komputery Apple'a), SPARC, RISC-V. Możesz się zastanawiać, po co tyle tego - no, oprócz zestawu rozkazów, różnic między archami jest wiele - np. ARM żre stosunkowo mało mocy, dlatego właśnie siedzi w telefonach, zamiast x86. Ale to już, jeśli jesteś ciekawy, do poczytania we własnym zakresie. :)

0

Czy x86 oznacza procesor 32 bit?
Co znaczą oznaczenia x86,i386,i586?
Czy dobrze mi się zdaje że oznaczają one procesor 32 biotwy który różni się tylko ilością obsługiwanych instrukcji?

0
  1. Tak.
  2. To są architektury procesorów.
  3. ?
0

Napisałem

Czy dobrze mi się zdaje że oznaczają one procesor 32 biotwy który różni się tylko ilością obsługiwanych instrukcji?

Na pewnym forum ktoś spytał o różnice między i386 a i586 na co mu odpowiedziano:

To są stare skróty z procesorów intelowskich:
80386
80486
80586
różnią się troszeczkę obsługiwanymi instrukcjami

#EDIT
@pingwindyktator Systemy 32-bitowe różnią się od 64-bitowych wieloma rzeczami. Dwie z nich wymienione w poście. "troszeczke inne instrukcje" to zbyt mało powiedziane.

0

Najbardziej ogólnie, tak: kompilując kod dla i386 (rzeczywiście pochodzi to od Intel 80386) pozbywasz się pewnych dodatkowych instrukcji procesora, które pojawiły się później, a przez które twój kod może być wydajniejszy - np. w okolicach powstawania procesora Intel 586, dziś znanego jako Pentium wprowadzano MMX, ale standardem był dopiero w szóstej generacji (i686), czyli Pentium II (i jego odpowiedniki, np. AMD K6). x86 to ogólna rodzina pewnej architektury procesorów, produkowanych przez Intela, AMD i kilka innych firm.

0

No a wielkość rekordu w virtual memory? A długość instrukcji?

0

@Ktos -

w okolicach powstawania procesora Intel 586, dziś znanego jako Pentium wprowadzano MMX,

Czyli jak ustawię sobie w kompilatorze architekture i586 to kompilator może zapisac moją aplikację przy użyciu jednej z instrukcji MMX co znaczy ze na orginalnym i386 program nie uruchomi sie/podczas wykonania wystapi błąd a specyfikacji mojej aplikacji napisze "procesor Intel Pentium lub nowszy?"

OK x86 odnosi sie do CPU 32 bit a jakie jest oznaczenie procesorow 64 bit - czy oznacza sie je AMD64 albo x86-64
Skoro mamy i386,i486,i586 to czy istnieją CPU 64 bit które obsługują więcej instrukcji a jeżeli tak to jak się je oznacza?

Na wikipedi czytamy o AMD64:

Powiększenie liczby widocznych dla użytkownika rejestrów pozwoliło na 5–15% zwiększenie wydajności.

Czy isntieją rejstry niewidoczne? Jakie moga mie zastosowanie?

Zastanawia mnie jeszcze jedno - CPU 64 bit maja jak podaje wikipedia

Adresowanie „RIP-relative”.
NX-bit
Rozkazy SSE.

Jak te funkcję się włącza czy wystarczy pogrzeba w kompilatorze? Co do NX-bit to na pewno ale co z pozostałymi?

0

64-bitowe procki Intela/AMD z reguły oznacza się jako x86-64 lub x86_64, rzadziej x64 (to głównie terminologia Microsoftu), z rzadka AMD64.
amd64 bierze się stąd, że rozwinięcie oryginalnego x86 na 64 bity jest właśnie dziełem AMD. Intel w tamtym czasie miał inną wizję i pracował nad Itanium - architekturą 64-bit, która nie była kompatybilna wstecz z x86. Jak widać, pomysł AMD bardziej się przyjął.

1 użytkowników online, w tym zalogowanych: 0, gości: 1