레이블이 X86인 게시물을 표시합니다. 모든 게시물 표시
레이블이 X86인 게시물을 표시합니다. 모든 게시물 표시

2024년 10월 1일 화요일

x86계열 스텐드 얼론 DVR 개발기

 2007년 개발 기안으로 나는 고급형 스텐드 얼론 DVR을 제안하였다.

사양은 당시로선 고급 사양인 CIF 해상도에 480프레임이 지원되는 DVR이었다.

코덱 칩은 소프트로직(SOFT LOGIC)사에서 개발한 SOLO라는 칩이 있었는데 목표사양에 적합했다. 하지만 문제가 있었는데, encoding은 되지만 decoding이 안되는 것이었다.

이를 해결하려면 decoding은 CPU (SOC)에서 해야 했다.

지금은 PC사양이 높아지고, 비디오 카드와 CPU에도 영상 관련 가속기능들이 생겨 큰 문제는 아니지만, 당시에는 MPEG4로 압축된 영상을 CIF 480 디코딩을 한다는 것은 PC에서도 쉽지 않은 일이었다.

몇몇 SOC 업체들과 미팅을 하다 눈에 들어오는 SOC를 발견하였다.

AMD geode LX800이다.

이 SOC는 다음과 같은 이점이 있었다.

  • 500Mhz 의 높은 성능

  • MMX 지원으로 영상 처리 일부 가속 가능

  • x86계열로 크로스 컴파일 불필요

SOC와 코덱을 선정한 후 개발 기안을 품의 받아 개발에 착수 하였다.

생각치 못한 첫번째 난관이 도래했다.

바로 BIOS다.

내가 x86을 우습게 생각했었다.

x86CPU니까 바로 보드를 찍어 리눅스를 설치하면 될 것이라 생각했는데, x86의 주변기기 자원을 리눅스로 전달 할 수 있는 BIOS가 필요한 것이었다.

당시 리눅스를 바로 돌릴만한 x86용 부트로더는 찾을 수 없었고

LX800에 기본 내장 된 기능들은 방대하였다.

X86의 특징중 하나인 시작시 16bit real mode로 시작하여 단계적으로 32bit protected paging 모드로 진입해야 한다는 것도 x86에서 부트로더를 개발하는데 저항감을 주는 원인중 하나인 것 같다.

불행 중 다행은 8086 시절 BIOS는 어셈블리 레벨로 어느 정도 파악을 하고 있었고, 32bit 초기시절 OS개발 프로젝트에 참여하였기 때문에 어느정도 지식이 있다는 점이었다.

이후 미친듯이 AT BIOS와 PCI bus 리소스관련 자료를 찾아 공부하였다.

AT BIOS 소스의 경우 예비군 훈련장까지 가지고 가서 볼정도로 발등에 불이 떨어져 있었다.

활용 가능한 opensource의 bios가 있는가도 찾아보았는데, 다행히도 open bios라고 제한적인 기능이지만 LX800의 레거시 장치의 자원을 지원하는 bios를 찾을 수 있었다.

드디어 BIOS 1차버전이 완성되고 주변 장치 정보를 LINUX에 잘 전달하는지 확인하였다.

부팅된다! 만세가 터져나왔다.

그런데 이상하다.

내장 peripheral 장치들은 잡히는데 중요한 PCI bus에 장착된 SOLO 코덱칩이 잡히지 않았다.

내가 사용한 open bios는 내장된 장치에 대한 부분은 있었지만 PCI bus에 대한 장치 탬색 및 열거 (enumeration)이 되지 않았다.

LX 800의 데이터시트를 보며 이 부분을 추가적으로 구현하였고, SOLO에서도 이와 관련 된 부분에 호환이 되지 않는 부분을 발견하여 SOLO의 VID와 PID를 발견하면 예외처리를 추가하여 장치 자원을 잡도록 하여 성공하였다.

이 후에도 생각보다 LX800의 소프트웨어 디코딩 성능이 안나와 패닉에 빠졌었지만, 다행히도 SOLO에 디코딩 통합형 버전이 나온다 하여 위기를 넘길 수 있었다.

무척이나 급했기 때문에 SOLO 칩은 드라이버 마저 완성되지 않았지만, 칩업체에 설득하여 데이터시트를 받아 (데이터 시트도 완성되지 않은 상태였다) 드라이버를 직접 개발하여 사용했다.

이 후 인연이 되어 SOLO 코덱 칩은 Hisilicon으로 넘어가기 전까지 계속 사용하였고, 드라이버는 자체 개발버전을 사용하였다.

여러 고비를 넘기고 제품이 완성되었지만 고급형 제품이 그렇듯 그렇게 많이 팔리진 않았다. 오히려 다음 프로젝트로 개발한 저가 ARM SOC로 개발한 저가형 H.264 DVR이 ADT에 납품 되는 등 많이 팔리게 되었다.

역시 고급형은 만드는 보람은 있지만, 매출은 저가형으로 올리는 것인가 보다.

x86계열 SOC는 이후로는 사용하지 않았고 앞으로도 그럴 것 같다.

이유를 정리해 보면

  • BIOS 개발이 힘들다. 저때는 legacy 타입으로 개발했지만 요즘은 UEFI 타입으로 개발해야 한다.

  • DVR이나 NVR로 쓰기에는 가성비가 좋지 않다. (가성비 좋은 칩들이 많아 나왔다)

  • 메인보드 개발이 힘들다. 성능이 앞서는 만큼 PCB 수준도 높게 요구하고, SMT 역시 쉽지 않았다. 하드웨어 담당자와 PCB 제조사 사장님들과 SMT 사장님들께서 고생이 많으셨다.

상세하게 적지 않았지만, 제조원가 절감을 위해서 치뤄야 할 고생이 매우 큰 제품이이었다.

나름 좋은 경험이었지만, 혹시라도 x86으로 임베디드 장비를 만들어야 할 상황이 온다면 산업용 메인보드를 구매하여 사용하라고 권장하고 싶다.

2024년 9월 23일 월요일

테스크 스위칭과 TSS

오랜만에 글을 쓴다.

일이 많아 글을 쓸 여유가 없다, 나이가 먹고 더 기억력이 나빠지기 전에 해왔던 생각들을 글로 남겨 놓는 것도 좋을 것 같아 쓰기 시작한다.


OS에서 여러 개의 TASK들을 돌아가며 돌리기 위해서는 운용할 TASK 리스트를 준비 해 두고, CPU의 타이머 인터럽트가 발생 할 때 실행 우선 순번이 높은 TASK쪽으로 복귀하는 식으로 multitasking 을 운용한다.

코어가 1개인 CPU (hyper threading 은 제외한다)에서 실행되는 multitasking은 결국 timer interrupt 에 의한 CPU 노가다 인 샘이다.

하지만 이것은 그만큼 CPU들의 성능이 비약적으로 빨라졌기 때문에 가능해 진 것이다.

일반적으로 timer interrupt는 x86 계열 CPU에서는 초 당 1000번 (1ms 간격) , 그 외 CPU에서는 대부분 초 당 100번 (10ms  간격) 으로 발생한다.

CPU가 느리다면 하나의 task 당 1ms, 혹은 10ms 에 실행할 수 있는 코드의 양은 매우 적기 때문에 매우 느리고 답답할 것이다.

하지만 근래 CPU들의 경우 클럭이 최소 500Mhz 부터 5GHz까지 높은 속도로 실행된다.

이 뜻은 클럭 당 1개의 명령을 수행한다고 가정할 때 10ms 인터럽트 간격 동안 5,000,000 ~ 50,000,000 개의 명령을 실행할 수 있다는 뜻이다.

즉, 초 당 위 명령 정도만 실행하는 task는 동시에 100개 가량 운용해도 속도 저하가 없다는 뜻이다.

이 외에도 OS 차원에서 대기 중인 task (sleep 이나 이벤트 대기)의 경우 아직 wake 상태가 아니면 실행 안 하는 등의 최적화를 통하여 multitasking의 효율은 더욱 높아지게 되었다.


그래도 여전히 multitasking에서 부담스러운 부분이 있는데 바로 context switching 이다.

즉 task 교환이다.

A라는 task에서 연산을 하던 중, 타이머 인터럽트가 발생하여 B라는 task로 이동할 때 해상 task가 마지막에 운용되던 상태를 그대로 복원해야 하는 작업이 context switching 시 수행된다.

task가 사용하던 stack과 register의 마지막 상태 들을 저장 및 복원해야 한다.

이를 위하여 x86에서는 TSS를 지원하고 ARM계열에서는 레지스터를 동시에 여러 개를 stack에 push 하는 명령을 지원하였다.

32bit 초기 시절 32bit OS개발 업무를 하던 당시, x86의 TSS라는 지원이 뭔가 고급스럽게 느껴지게 되었고, 이 후 tss를 지원하지 않는 OS나 CPU들이 답답하게 느껴 졌었다.


TSS는 task state segment 라 하며 x86에서 테스크의 마지막 상태를 저장하고, 복원하기 위한 메모리 영역과 descriptor 였다.  따라서 테스크 이동을 할 경우 TSS의 NT 기능을 활용하면 FPU등 부분만 주의만 하면 비교적 고급스럽게 context switching을 할 수 있게 되었다.


하지만 시간이 흐르고 64bit 시절이 오며 x86역시 TSS를 호환상 유지하기는 하지만 context switching에서 큰 비중을 차지하지 않게 되었다.

이 시절이 되니, 나에게도 역시 TSS가 context switching에 더 이상은 유용해 보이지 않았다.

이유는 CPU의 많은 확장과 다양성 때문이었다.

예전에는 context switching을 하기 위하여 저장하고 복원해야 하는 것들이 general, stack, FPU 레지스터 정도였다.

하지만 지금은 CPU 종류 별로 다양한 부가 기능을 지원하다 보니, SIMD 계열 레지스터도 다양하게 늘어났고, NPU 연산까지 추가되고 있기 때문에 OS에서는 context switching 시 CPU가 지원하는 기능을 파악하고, 그에 맞춰 저장 및 복원해야 하는 항목들이 달라지는 상황이 온 것이다.

이럴 때 편하기는 하지만, 유연성이 떨어지는 TSS의 경우 효율이 좋기 어렵고 CPU 개발에 부담만 가중 시키는 것이라 생각된다.


세상이 변하면서 TSS에 대한 나의 생각도 변하게 되었다는 것이 생각나 글을 적어보았다.

앞으로 글을 쓸 거리가 생각나고 시간이 날 때 마다 글을 쓸 예정이다.

그럼 다음에...