2

버퍼를 인수로 취하는 시스템 호출 write이 있다고 가정 해 보겠습니다. 이 버퍼 메모리는 사용자 주소 공간의 일부입니다.데이터 시스템 호출 중 커널 공간에 복사

쓰기 호출이 어떻게 더 성공합니까?

전체 버퍼가 커널 공간에 복사되고 프로세스가 선점되고 다른 프로세스에 CPU가 주어지고 새로운 프로세스가 다른 시스템 호출을 실행한다고 가정하면 버퍼를 덮어 쓸 수 있습니다 이전 write 호출 중

과 같은 케이스는 어떻게 처리됩니까? 또는 사용자 공간에서 커널 공간으로 데이터 복사가 전혀 이루어지지 않는 완전히 다른 메커니즘이 있습니까?

+0

왜 커널이 프로세스간에 버퍼를 공유합니까? 또는 왜 다른 시스템 호출이 처음에 동일한 버퍼를 공유합니까? –

답변

3

일반적으로 사용자 공간에서 커널 (모 놀리 식 커널)으로 복사 할 필요는 없습니다. 가상 메모리 시스템의 경우, 프로세스에 할당 된 페이지는 커널에 의해 읽고 쓸 수 있습니다. 프로세스가 커널에 할당 된 페이지에 액세스 할 수 없으므로 다른 방법으로 데이터를 복사해야합니다.

예를 들어, x86-64를 사용하는 linux에 대해 write 시스템 콜을 사용하면 프로세스는 파일 디스크립터, 버퍼 주소 및 크기를 사용하여 write를 호출합니다. writerax 방법 (1), 레지스터에 인수 (rdi, rsi, rdx [r10, r8])으로 시스템 호출 번호를 배치하고, syscall 명령 (커널 들어가는) 실행한다. 호출은 레지스터를 커널 스택으로 푸시하는 핸들러로 전달되고 호출 번호가 실행됩니다. 포인터 안에있는 데이터를 커널 메모리에 명시 적으로 복사 할 필요는 없습니다.

마이크로 커널 (Mach, L4 등)은 다릅니다.

+0

정확합니다. 동기식 호출에서는 복사가 필요하지 않습니다. 비동기 호출을 사용하면 사용자 코드에 의해 확장 된 수명이 할당 된 버퍼 포인터/길이를 전달하여 복사를 피할 수 있으며 나중에 콜백에서 소비 및 릴리스를 위해 반환됩니다. –

+0

@ Jason 시스템 호출을 실행하는 동안 컨텍스트 전환이 발생하면 어떻게 될까요? 새로운 프로세스는 "di, rsi, rdx [, r10, r8]"이 가리키는 레지스터를 덮어 쓸 시스템 콜을 발행합니다. 어떻게 처리됩니까? –

+1

@SumitTrehan 그렇기 때문에 컨텍스트 스위치에 레지스터 상태를 저장할 수 있습니다. 프로세스가 CPU에서 다시 스케줄되기 전에 레지스터 상태를 복원 할 수 있습니다. 이것은 ('rax') 시스템 콜에서 값을 반환하는 레지스터를 제외합니다. – Jason

0

(이 도움이 될) 두 과정 사이에 일반적입니다, 우리는 커널 공간에 대한 몇 가지 잠금 장치를 제공해야한다 데이터 충돌 또는 경쟁 조건으로부터 보호하십시오.