1. 개념 요약

셸은 사용자가 입력한 한 줄을 명령으로 해석해 실행하는 프로그램이다. 키 입력을 줄 단위로 모았다가 엔터가 들어오면 그 줄을 명령으로 다룬다.

go-os의 셸은 앞 단계에서 만든 키보드 입력과 콘솔 출력, heap을 묶어 만든다. 화면에 프롬프트를 띄우고 입력을 받아 help 같은 명령을 실행한다.

2. 왜 필요한가

이전 단계의 커널은 부팅 시 정의된 초기화 절차와 키보드 문자 출력만 수행했다. 입력된 문자열을 명령으로 해석하고 기능을 실행하는 인터페이스는 없었다.

셸을 추가하면 사용자가 명령을 입력해 커널 상태를 조회하거나 화면을 초기화하는 기능을 실행할 수 있다.

3. 등장 배경

인터럽트에서 키보드 입력을 받았고 그 위 단계에서 스크롤되는 콘솔과 heap을 갖췄다. 각 조각은 동작했지만 입력을 명령으로 해석하는 층은 없었다.

기존 OnKey는 입력된 문자를 화면에 출력했다. 셸을 구현하려면 입력을 한 줄로 저장하고, Enter 입력 시 명령과 인자로 해석하는 단계가 추가로 필요했다.

4. 필요한 조건

조건설명
키보드 입력IRQ1로 키 입력을 받아 글자로 바꿀 수 있어야 한다.
콘솔 출력프롬프트와 명령 결과를 화면에 찍을 수 있어야 한다.
줄 버퍼엔터가 올 때까지 입력한 글자를 모아 둘 공간이 있어야 한다.

5. 핵심 구성 요소

구성 요소역할
줄 버퍼엔터 전까지 입력한 글자를 모은다.
OnKey 통합글자를 화면에 찍으면서 줄 버퍼에도 쌓는다.
runCommand줄 버퍼를 명령 이름과 비교해 실행한다.
프롬프트입력을 기다리는 자리를 표시한다.

6. 동작 흐름

flowchart TD
    A["키 입력"]
    B{"어떤 키인가"}
    C["글자: 화면에 찍고 줄 버퍼에 추가"]
    D["백스페이스: 버퍼가 비지 않았으면 한 글자 지움"]
    E["엔터: runCommand 실행"]
    F["줄 버퍼 비우고 새 프롬프트"]

    A --> B
    B -- 글자 --> C
    B -- 백스페이스 --> D
    B -- 엔터 --> E --> F

키가 들어오면 종류에 따라 갈린다. 글자면 화면에 찍고 줄 버퍼에 쌓는다. 백스페이스면 버퍼와 화면에서 한 글자 지운다. 엔터면 그때까지 모은 줄을 명령으로 실행하고 버퍼를 비운 뒤 새 프롬프트를 띄운다.

7. 상태 변화

단계줄 버퍼 상태
프롬프트 직후길이 0. 비어 있다.
글자 입력글자를 끝에 더하고 길이를 1 늘린다.
백스페이스길이가 0보다 클 때만 1 줄인다.
엔터 처리 후명령을 실행하고 길이를 0으로 되돌린다.

8. 코드나 설정에서 나타나는 형태

명령 해석은 줄 버퍼와 명령 이름을 바이트 단위로 비교하는 일이다. 문자열 비교 런타임을 끌어오지 않으려고 직접 비교한다.

func bufEq(s string) bool {
	if lineLen != len(s) {
		return false
	}
	for i := 0; i < lineLen; i++ {
		if lineBuf[i] != s[i] {
			return false
		}
	}
	return true
}

이 함수로 입력 버퍼와 명령 이름이 같은지 확인한다. 전체 문자열이 일치하면 인자 없는 명령으로 처리하고, 정해진 접두사 뒤에 내용이 있으면 인자가 포함된 명령으로 처리한다.

9. 자주 헷갈리는 지점

백스페이스는 줄 버퍼가 비어 있을 때 막아야 한다. 빈 줄에서 지우면 프롬프트나 앞선 출력까지 지워질 수 있다.

셸은 키 입력으로 동작하므로 화면 없이 검증하기 어렵다. QEMU monitor의 sendkey로 스캔코드를 주입하면 키보드 없이도 명령을 입력할 수 있다. 명령 실행 결과를 시리얼로도 보내면 화면을 보지 않고 확인할 수 있다.

10. 확인 방법

확인 대상확인 방법
줄 입력글자를 주입하고 화면에 같은 글자가 쌓이는지 본다.
명령 실행help와 엔터를 주입하고 명령 목록이 출력되는지 본다.
인자 명령echo <text>를 주입하고 뒤따르는 글자가 출력되는지 본다.

go-os는 sendkeyhelp를 주입하면 명령 목록을 출력하고 시리얼로 CMD help를 보낸다. 화면 없이 이 출력을 받아 동작을 확인한다.

11. 다음에 볼 개념

지금 셸은 명령 세 개만 알고 입력 편집은 백스페이스뿐이다. 명령을 맵에 등록해 동적으로 늘리는 것, 입력을 인자 토큰으로 나누는 것, 커서 이동과 명령 기록을 더하는 것이 다음 과제다. 그 위에 메모리나 클러스터 상태를 보여 주는 실제 운영 명령을 올릴 수 있다.

참고 자료