IT 공부/운영체제9 라이브러리와 링커 ▷ 처음 C언어를 배울 때는 완전히 착각을 한 부분이 바로 부분이었다. 나는 printf()와 같은 함수의 구현 소스코드가 저 헤더 파일에 있는 줄 착각했다. 그도 당연할 것이, printf() 함수의 구현 소스코드를 본 적이 없었기 때문이다.▷ 그러나 함수 선언 부인 헤더 파일은 그저 해당 소스코드(텍스트 파일)를 재배치 가능한 파일(오브젝트 파일)로 컴파일하기 위해 존재하는 것일 뿐이다. printf()의 구현체를 발견하질 못했으니 오브젝트 파일 내의 바이너리로 포함할 수 없다. 이러한 미해결 호출 함수의 심볼은 ELF(unix/linux) 혁식이든 COFF(windows)이든 따로 헤더에 저장되고, 이것을 링커가 해결한다.▷ 호출 가능한 실제 printf() 함수의 구현 바이너리는 라이브러리 형.. 2024. 12. 21. [리눅스] - 마운트란 ▷ mount란 외부 저장 장치를 다루게 하는 리눅스만의 특별한 방식이다.▷ Windows는 리눅스의 마운트와 조금 다르게 동작하는데, C:/ D:/ 이런 식으로 아예 저장 장치만의 별도의 독립된 구획이 따로 있는 것처럼 보인다. ▷ 그러나 리눅스는 외부 저장 장치를 루트 디렉터리(/)에서 시작해 어떤 위치의 디렉터리에 통합시켜버린다.▷ 예를 들어, USB 디바이스의 파일 시스템(FAT 형식)을 읽어서 특정 위치 (/mnt/usb) 디렉터리에 통합시켜버리는 것이다.▷ 이렇게 하면 리눅스 사용자 입장에서는 외부 저장 장치 내부의 파일들을 루트 디렉터리에서 시작하는 디렉터리 시스템의 일부라고 쉽게 받아들일 수 있는 것이다. 마치 하드디스크나 USB 안의 파일들이 원래 그 디렉터리에 있었던 것처럼 말이다.▷이.. 2024. 12. 20. [64비트 멀티코어 OS 원리와 구조 1] - 목차 기준으로 흐름 요약 3장. 64비트 프로세서의 이모저모- x86-64 프로세서는 호환성을 위해 16비트 모드부터 부팅 시작.- 따라서 16비트, 32비트를 거쳐 64비트 모드로 전환이 필요.- 각 모드 별 레지스터의 의미와 메모리 접근 방식이 다르므로, 상세 사항을 알지 못하면 전환을 할 수 X.▶ 개괄 : 1) 운영모드에는 어떤 것이 있으며, 각 모드마다 2) 레지스터 의미가 무엇인지, 그리고 3) 메모리 관리가 어떻게 다른지 알아본다. 4장. 내 PC를 부팅하자!- OS의 진입점(entry point)인 부트로더(boot loader)가 어떻게 시작되는지 아는 것이 4장의 목적.- x86 프로세서와 OS의 진입점 사이에는 BIOS가 있다.- BIOS가 부트로더를 어떻게 실행하는지 모르면 부트로더를 작성할 수 없으므로 .. 2024. 12. 18. [2024.11.21] - IRETQ 명령어 새롭게 알게 된 내용 정리 ▷ IRTG 명령어는 인터럽트 수행이 끝난 후에 핸들러 함수의 끝부분의 마지막 명령어다. 이것은 IST 스택에 프로세서가 직접 쌓아준 여러 레지스터 데이터들(Flags, CS, SS, RIP, RSP)를 한 꺼번에 복구시키는 명령어다. ▷ IDT 인터럽트 게이트 디스크립터 테이블에 우리는 인터럽트 핸들러 함수의 포인터를 저장하고, CS(코드 세그먼트 설렉터)와 IST, DPL, 타입을 저장한다. 이때 타입에는 인터럽트/트랩 두 종류 중 하나를 선택할 수 있는데, 보통 인터럽트를 선택한다. 트랩은 인터럽트 핸들러 수행 도중에 다른 인터럽트를 또 받을 수 있게 설정하는 것이다. 인터럽트는 핸들러 수행 도중에 다른 인터럽트 신호 발생 시 무시하는 역할을 수행한다. ▷ 인터럽트 타입은 해당 인터럽트 신호가 발생.. 2024. 11. 21. OS 배운거 정리 2024.10.29 - rex, 오퍼랜드 사이즈 접두사 개념 - 멀티코어 원리 책 읽고 추가 내용 정리한 것. (3장 내용)- 원래 리얼모드나 32비트 모드에서 32비트, 그리고 64비트 레지스터나 값에 접근하는 것은 불가능함. 16비트 프로세서가 32비트 값을 메모리에서 읽어와서 레지스터에 저장할 수는 없음.- 하지만 64비트 프로세서는 이론적으로는 이런 명령어 실행이 가능하긴 함. 그래서 64비트 모드의 경우, 설령 리얼모드 혹은 보호모드에서 동작하는 코드라고 하더라도 접두사를 통해 다양한 크기의 레지스터에 접근할 수 있도록 허락함.- 이게 86페이지의 표에 나타나 있음.- 내가 어셈블리어로 코딩한 값을 어떤 크기로 읽어야 하는지 알려주는 개념.. 접두사를 사용하면 리얼모드와 보호모드에서 확장된 크기의 값을 사용할 수 있음. 즉, 16비트 모드에서 mov ea.. 2024. 10. 29. [OS] - 프로세스와 스레드의 차이 (매우 중요) 1. 멀티프로세스가 필요한 경우 (vs 쓰레드) 먼저, 멀티프로세스와 멀티쓰레드간 차이에 대해 고심하는 것이 은근히 까다로운 이유는 옛날과 현재의 멀티태스킹 프로그래밍 관점이 다르기 때문에 발생한다. 예를 들어, 웹 서버를 구현해야 한다고 생각해보자. 웹 서버는 한 번에 여러 명의 사용자들에게 서비스를 제공해야 한다. OS가 TCP 프로토콜을 수행하고, 소켓을 연결하고, HTTP 데이터를 파싱하고 해석하고, 이 데이터를 다시 식별된 URI를 담당하는 웹 서버의 특정 로직에게 넘겨주고, ... 이런 일련의 동작을 하나의 사용자에게 할당해야 한다. 옛날에는 이러한 요구를 한 번에 수행하기 위해 자식 프로세스를 생성하여 각각의 사용자의 요구를 처리할 수 있도록 프로그래밍했다. 물론 프로세스 생성 대신, 한 명.. 2023. 12. 28. [OS] - 운영체제의 멀티 쓰레드 스케쥴링 및 개수 제약 1. 커널 쓰레드와 사용자 쓰레드 차이 과거 오래된 유닉스 시스템에서는 멀티쓰레드를 지원해주지 않았고 멀티프로세스만을 지원했다. 그러나 시간이 흘러 멀티쓰레드를 지원해주는 OS가 생겨나면서 커널이 쓰레드 단위를 인식하고 직접 관리나 스케쥴링을 해주는 서비스를 제공해줬다. 이것이 커널 쓰레드다. 물론 커널 쓰레드를 거치지 않고도 쓰레드 기능을 구현해볼 수는 있다. 이것이 사용자 쓰레드다. 하지만 사용자 쓰레드는 사용하는 프로그래밍 언어를 통해 직접 구현해보거나, 혹은 쓰레드를 관리해주는 라이브러리를 가져와 사용해야 한다. 현대 운영체제는 쓰레드와 프로세스를 모두 관리해주기 때문에 사용자 공간 자체에서 직접 쓰레드를 구현해 사용하는 경우는 없는 편이다. 게다가 사용자 쓰레드를 커널과 독립적으로 사용하는 경우.. 2023. 12. 27. [리눅스] - 인터프리터, 가상머신, 그리고 실행 파일의 명령어 구조 차이 1. 실행 파일의 경우 (feat. C언어) C언어로 작성한 소스코드는 리눅스에 내장된 gcc 컴파일러를 통해 바로 시스템에서 실행 가능한 프로그램이 된다. gcc로 컴파일을 완료하면 위와 같이 ./hello 를 통해 즉시 실행할 수 있다. 이때, 어떤 프로그램을 매개하지 않는 모습을 확인할 수 있다. 컴파일된 파일은 시스템에서 바로 실행할 수 있는 것이다. 다만 이러한 이유로 C언어 개발자는 플랫폼의 기능을 사용하기 위해 운영체제 시스템과 API에 대한 정보를 배워야 하는 단점이 있다. 2. 가상 머신의 경우 (feat. 자바) 자바의 강점은 자바 가상 머신을 통해 컴퓨터와 OS 장치를 통째로 추상화하여 통일된 규격의 인터페이스를 사용한다는 점이다. 이 지점에서 C언어 개발자와는 달리 자바 개발자는 운.. 2023. 12. 18. [리눅스] - 심볼릭 링크와 하드 링크 정리 및 사용 용례 1. 용어 정리 링크는 윈도우즈의 "바로가기" 아이콘을 만드는 것과 흡사하다. 데이터 블록은 실제 파일의 데이터를 의미하며, 하드 디스크 어딘가에 저장된 것이다. inode는 원본 파일의 데이터에 대한 정보와 위치를 알려주는 메타데이터다. 소유자, 권한, 생성 시간 등 "ls --long"으로 알아낼 수 있는 정보들이 사실 inode에 담긴 것이다. 하드 링크 파일은 리눅스의 사용자가 파일을 이용할 수 있도록 만든 일종의 아이콘과 같은 것이다. 리눅스 사용자는 파일을 찾을 때 inode를 직접 참조할 수 없다. 대신 원본 파일에 대한 링크를 통해 접근 가능하다. 즉, 하드 링크는 사실 바로 그 파일의 이름이다. (이러한 이유로, 사실 하드 링크는 그것이 링크로 생성되었는 것인지 아니면 원본인지 구분해내기.. 2023. 12. 18. 이전 1 다음