vfs — 가상 파일시스템 제어¶
vfs 모듈은 파일시스템 객체를 생성하고 이를 가상 파일시스템에 마운트/언마운트하는 함수를 포함합니다.
파일시스템 마운트¶
일부 포트는 가상 파일시스템(VFS)과 이 VFS 안에 여러 개의 “실제” 파일시스템을 마운트할 수 있는 기능을 제공합니다. 파일시스템 객체는 VFS의 루트에 마운트하거나, 루트 아래에 위치한 하위 디렉터리에 마운트할 수 있습니다. 이를 통해 Python 프로그램이 보게 되는 파일시스템을 동적이고 유연하게 구성할 수 있습니다. 이 기능을 갖춘 포트는 mount() 및 umount() 함수를 제공하며, 경우에 따라 VFS 클래스로 표현되는 다양한 파일시스템 구현을 제공할 수도 있습니다.
- vfs.mount(fsobj: Any, mount_point: str, *, readonly: bool = False) None¶
파일시스템 객체 fsobj 를 mount_point 문자열로 지정한 VFS 내 위치에 마운트합니다. fsobj 는
mount()메서드를 가진 VFS 객체이거나 블록 디바이스일 수 있습니다. 블록 디바이스인 경우 파일시스템 유형이 자동으로 감지됩니다(인식되는 파일시스템이 없으면 예외가 발생합니다). mount_point 는 fsobj 를 루트에 마운트하려면'/'일 수 있고, 루트 아래의 하위 디렉터리에 마운트하려면'/<name>'일 수 있습니다.readonly 가
True이면 파일시스템이 읽기 전용으로 마운트됩니다.마운트 과정에서 파일시스템 객체의
mount()메서드가 호출됩니다.mount_point 가 이미 마운트되어 있으면
OSError(EPERM)이 발생합니다.
- vfs.mount() List[Tuple[Any, str]]
mount()를 인자 없이 호출하면 모든 활성 마운트 지점을 나타내는 튜플의 리스트를 반환합니다.반환되는 리스트는 [(fsobj, mount_point), …] 형식입니다.
- vfs.umount(mount_point: str | Any) None¶
파일시스템을 언마운트합니다. mount_point 는 마운트 위치를 나타내는 문자열이거나, 이전에 마운트된 파일시스템 객체일 수 있습니다. 언마운트 과정에서 파일시스템 객체의
umount()메서드가 호출됩니다.mount_point 를 찾을 수 없으면
OSError(EINVAL)이 발생합니다.
- class vfs.VfsFat(block_dev: AbstractBlockDev)¶
FAT 파일시스템 포맷을 사용하는 파일시스템 객체를 생성합니다. FAT 파일시스템의 저장소는 block_dev 가 제공합니다. 이 생성자로 만든 객체는
mount()를 사용하여 마운트할 수 있습니다.- static mkfs(block_dev: AbstractBlockDev) None¶
block_dev 에 FAT 파일시스템을 구축합니다.
- class vfs.VfsRom(buffer: bytes | bytearray | memoryview)¶
ROMFS 읽기 전용 파일시스템 포맷 을 사용하는 파일시스템 객체를 생성합니다.
buffer는 유효한 ROMFS 이미지를 담고 있으면서 버퍼 프로토콜을 지원하는 객체(bytes,bytearray또는memoryview)여야 합니다.이 생성자로 만든 객체는
mount()를 사용하여 마운트할 수 있습니다.mpremote 로 ROMFS 이미지를 구축하고 배포하는 방법을 포함한 전체 세부 사항은 ROMFS 사용하기 를 참조하세요.
- vfs.rom_ioctl(op: int, *args: Any) Any¶
디바이스의 읽기 전용 메모리(ROM) 파티션에 접근하기 위한 저수준 인터페이스입니다. 지원되는 연산은 다음과 같습니다:
호출
동작
rom_ioctl(1)사용 가능한 ROM 파티션의 개수를 반환합니다.
rom_ioctl(2, id)파티션
id를memoryview로 반환합니다.rom_ioctl(3, id, length)쓰기를 준비하기 위해 파티션
id의 처음length바이트를 지웁니다. 최소 쓰기 정렬 크기를 바이트 단위로 반환합니다.rom_ioctl(4, id, offset, buf)buf를 파티션id의 바이트offset위치에 씁니다.rom_ioctl(5, id)파티션
id에 대한 쓰기 시퀀스를 마무리합니다(캐시 플러시 등).이 연산들은 일반적으로 ROMFS 이미지를 배포할 때 mpremote 에 의해 간접적으로 호출됩니다. 대부분의 애플리케이션은 이를 직접 호출할 필요가 없습니다.
블록 디바이스¶
블록 디바이스는 블록 프로토콜을 구현하는 객체입니다. 이를 통해 디바이스가 MicroPython 파일시스템을 지원할 수 있습니다. 물리적 하드웨어는 사용자 정의 클래스로 표현됩니다. AbstractBlockDev 클래스는 그러한 클래스를 설계하기 위한 템플릿입니다. MicroPython이 실제로 이 클래스를 제공하지는 않지만, 실제 블록 디바이스 클래스는 아래에 설명된 메서드를 구현해야 합니다.
이 클래스의 구체적인 구현은 일반적으로 하드웨어(예: 플래시 메모리)의 메모리 유사 기능에 대한 접근을 허용합니다. 블록 디바이스는 지원되는 임의의 파일시스템으로 포맷할 수 있으며 os 메서드를 사용하여 마운트할 수 있습니다.
아래에 설명된 두 가지 블록 프로토콜 변형을 사용하는 블록 디바이스 구현 예제는 파일시스템 다루기 을 참조하세요.
단순 인터페이스와 확장 인터페이스¶
다양한 사용 사례를 지원하기 위해 readblocks 및 writeblocks 메서드에는 두 가지 호환 시그니처가 있습니다(아래 참조). 특정 블록 디바이스는 둘 중 하나를 구현하거나 둘 다 동시에 구현할 수 있습니다. 두 번째 형태(offset 매개변수가 있는 형태)를 “확장 인터페이스”라고 합니다.
일부 파일시스템은 쓰기 연산에 대한 더 많은 제어가 필요합니다. 예를 들어 지우지 않고 하위 블록 영역에 쓰는 경우 등이며, 이때 블록 디바이스가 확장 인터페이스를 지원해야 합니다.
- class vfs.AbstractBlockDev¶
블록 디바이스 프로토콜을 위한 문서화 템플릿입니다. MicroPython은 실제로 이 클래스를 노출하지 않으며, 사용자 정의 블록 디바이스 클래스가 구현해야 하는 메서드를 문서화하기 위해서만 여기에 표시됩니다. 생성자 인자는 전적으로 구현에 달려 있습니다(일반적으로 플래시 버스, 칩 셀렉트 핀, 섹터 크기 등).
- readblocks(block_num: int, buf: bytearray) None¶
- readblocks(block_num: int, buf: bytearray, offset: int) None
디바이스에서 buf 로 바이트를 읽습니다. 두 가지 오버로드가 단순 및 확장 인터페이스를 노출합니다.
단순 형식 (
readblocks(block_num, buf)): 블록 인덱스 block_num 부터 시작하여 전체 블록을 읽습니다.len(buf)는 블록 크기의 배수여야 하며, 읽는 블록 수는len(buf) // block_size입니다.확장 형식 (
readblocks(block_num, buf, offset)): 블록 block_num 내의 바이트offset부터 시작하여len(buf)바이트를 읽습니다. 반드시 전체 블록 단위일 필요는 없습니다. 파일 시스템이 서브 블록 단위의 읽기 접근이 필요할 때 이 형식을 사용하세요.
- writeblocks(block_num: int, buf: bytes) None¶
- writeblocks(block_num: int, buf: bytes, offset: int) None
buf 의 바이트를 디바이스에 씁니다.
단순 형식 (
writeblocks(block_num, buf)): 블록 인덱스 block_num 부터 시작하여 전체 블록을 씁니다.len(buf)는 블록 크기의 배수여야 하며, 쓰는 블록 수는len(buf) // block_size입니다. 기반 하드웨어에서 필요로 하는 경우 각 대상 블록을 먼저 지우는 것은 구현체의 책임입니다.확장 형식 (
writeblocks(block_num, buf, offset)): 블록 block_num 내의 바이트offset부터 시작하여len(buf)바이트를 씁니다. 반드시 전체 블록 단위일 필요는 없습니다. 기록되는 바이트만 변경될 수 있으며, 영향을 받는 블록이 사전에ioctl(6, block_num)호출을 통해 지워졌는지 확인하는 것은 호출자의 책임입니다. 이 형식의 구현체는offset이 0인 경우에도 절대로 블록을 암묵적으로 지워서는 안 됩니다.
- ioctl(op: int, arg: int) int | None¶
블록 디바이스를 제어하고 매개변수를 조회합니다. 수행할 연산은 op 로 지정되며, 다음 정수 중 하나입니다:
1 – 디바이스를 초기화합니다(arg 는 사용되지 않음)
2 – 디바이스를 종료합니다(arg 는 사용되지 않음)
3 – 디바이스를 동기화합니다(arg 는 사용되지 않음)
4 – 블록 수를 가져오며, 정수를 반환해야 합니다(arg 는 사용되지 않음)
5 – 블록의 바이트 수를 가져오며, 정수를 반환하거나
None을 반환해야 하고 후자의 경우 기본값 512가 사용됩니다(arg 는 사용되지 않음)6 – 블록을 지우며, arg 는 지울 블록 번호입니다
최소한
ioctl(4, ...)는 처리되어야 합니다. 확장 인터페이스를 사용하는 파일시스템은 추가로ioctl(6, ...)를 필요로 합니다. 다른 연산의 필요 여부는 하드웨어에 따라 다릅니다.확장 인터페이스를 사용하는 파일시스템은
writeblocks(block, ...)를 호출하기 전에ioctl(6, block)을 발행하여, 하드웨어가 요구하는 경우 드라이버가 먼저 블록을 지울 수 있도록 합니다. 드라이버는 대신ioctl(6, block)을 가로채 0(성공)을 반환하면서, 지우기가 필요한 시점을 스스로 감지하는 책임을 맡을 수도 있습니다.별도로 명시되지 않는 한
ioctl(op, arg)는None을 반환할 수 있습니다. 따라서 구현은 사용하지 않는op값을 무시할 수 있습니다.op가 처리되는 경우, 연산 4와 5의 반환값은 위에서 설명한 대로입니다. 다른 연산은 성공 시 0을, 실패 시 0이 아닌 값을 반환해야 하며, 반환되는 값은OSErrorerrno 코드입니다.