2017-10-23 13 views
2

나는 커널 모듈의 구현을 읽으려고 노력해 왔고, 나는이 코드 조각에 걸려 넘어지고있다. 다음과 같이리눅스 커널의 IS_ALIGNED 매크로는 무엇을합니까?

unsigned long addr = (unsigned long) buf; 

if (!IS_ALIGNED(addr, 1 << 9)) { 
    DMCRIT("@%s in %s is not sector-aligned. I/O buffer must be sector-aligned.", name, caller); 
    BUG(); 
} 

IS_ALIGNED 매크로는 커널 소스에 정의되어

#define IS_ALIGNED(x, a)  (((x) & ((typeof(x))(a) - 1)) == 0) 

나는 데이터가 작동하는 데이터 타입의 크기에 따라 정렬되어야 이해하지만, 난 아직도 이해가 안 돼요 코드가하는 일.

1 씩 9 시프트 한 다음 1을 빼면 111111111이됩니다. 그러면 111111111은 비트와 - 및 x를 사용합니다.

왜이 코드가 작동합니까? 바이트 정렬을 어떻게 확인합니까?

답변

1

프로그래밍하는 시스템에서는 특정 바이트 수에 맞춰 메모리 주소가 필요합니다. 즉, 몇 개의 최하위 비트가 0입니다.

기본적으로! IS_ALIGNED (addr, 1 < < 9)는 addr이 512 바이트 (2^9) 경계에 있는지 (마지막 9 비트는 0인지) 확인합니다. 이는 플래시 메모리가 큰 블록으로 분할되어 지워지거나 하나의 단위로 기록되어야하기 때문에 플래시 위치를 지울 때 공통적 인 요구 사항입니다.

이것에 대한 또 다른 응용 프로그램이 있습니다. 나는 modulo 기능을 가진 특정 DMA 컨트롤러로 작업하고 있었다. 기본적으로 이는 주소의 마지막 몇 비트 (이 경우 대상 주소) 만 변경할 수 있음을 의미합니다. 이는 DMA 컨트롤러를 사용하는 방식에서 실수로 인한 메모리를 보호하는 데 유용합니다. 문제는, 처음에는 DMA 대상 버퍼를 모듈러스 값에 맞추도록 컴파일러에 알리는 것을 잊었습니다. 이로 인해 엄청나게 흥미로운 버그가 발생했습니다 (때로는 덮어 쓰는 DMA 컨트롤러를 사용하는 것과 무관 한 무작위 변수).

"매크로 코드는 어떻게 작동합니까?"까지, 모든 0으로 끝나는 숫자에서 1을 빼면 모든 숫자로 끝나는 숫자가됩니다. 예 : 0b00010000 - 0b1 = 0b00001111. 이것은 필요한 정렬 바이트의 정수에서 2 진 마스크를 만드는 방법입니다. 이 마스크에는 0 값을 확인하는 데 관심이있는 비트의 마스크 만 있습니다. 최하위 비트의 마스크를 포함하는 마스크와 주소를 AND 한 후, 최하위 9 비트 (이 경우)가 0 인 경우에만 0을 얻습니다.

"왜 정렬해야합니까?"이것은 플래시 메모리의 내부 구성입니다. 플래시를 지우고 쓰는 것은 훨씬 덜 직접적인 과정이며 일반적으로 메모리 셀에 로직 레벨 이상의 전압이 공급되어야합니다. 쓰기 및 삭제 작업을 1 바이트 단위로 가능하게하는 데 필요한 회로는 드물게 사용되는 많은 실리콘 공간을 낭비합니다. 기본적으로 플래시 칩을 설계하는 것은 통계 및 트레이드 오프 게임 (엔지니어링 분야의 다른 모든 제품과 마찬가지로)이며 통계는 그룹에서 쓰기 및 지우기가 가장 좋은 방법입니다.

추가 비용없이 드라이버 및 커널 코드를 읽는 중이 유형의 많은 것을 보게 될 것입니다. 이 기사의 내용을 숙지하는 것이 도움이 될 수 있습니다 (또는 적어도 참조 용으로 유지하십시오). https://graphics.stanford.edu/~seander/bithacks.html

+0

예, 커널 모듈은 HDD에 대한 쓰기 저장 SSD 캐시를 만드는 데 사용됩니다. 따라서 응용 프로그램은 플래시 메모리를 사용합니다. 쓰기간에 플래시를 지워야한다는 것을 이해합니다. 마지막 몇 비트가 0인지 확인해야하는 이유에 대해 자세히 설명해 주시겠습니까? – user6337

+0

죄송합니다. 왜 메모리 주소가 512 바이트 경계에 정렬되도록 메모리 주소가 마지막 9 개의 항목을 0으로 가져야하는지 알 수 있습니다. 블록인지 또는 512 바이트인지 여부를 알고 있습니까? – user6337

+0

"sector-aligned"오류 메시지에서 hat이 사용되었습니다. 나는 블록 대 섹터 대 페이지의 정의의 차이점을 잊어 버렸다. 지금 당장 살펴보면, 페이지는 가장 작은 WRITE 단위입니다. 섹터 또는 블록은 최소 ERASE 단위입니다. – Dmitri