C에서 Raspberry Pi 용 OS 작성


19

Baking Pi 튜토리얼을 이미 찾았 지만 어셈블리 언어 만 사용 합니다 . 나는 첫 수업을 따랐지만 이미 C를 어떻게 사용하는지 궁금합니다. 그들이 더 높은 수준의 언어를 발명 한 이유가 있습니다. C 코드를 객체 ( .o) 파일로 컴파일 하려고 시도했습니다.

.section .init
.globl _start
_start:

bl main

loop$:
b loop$

다른 객체 파일에 연결하여 서로 연결하여 얻습니다 kernel.img. 그런 다음 이미 존재하는 커널을 내 것으로 교체했지만 C 코드를 실행하지 않습니다. 내가 작성한 C 코드는 OK LED를 켜고 돌아온다 loop$: b loop$. 그러나 OK LED가 무작위로 몇 번 깜박 인 다음 꺼집니다. 내 C 코드는 다음과 같습니다.

int main(int argc, char ** argv) {
    volatile unsigned *gpioAddr = (volatile unsigned *)0x20200000;
    *(gpioAddr + 4) = 1 << 18;
    *(gpioAddr + 40) = 1 << 16;
    return 0;
}

Raspberry Pi에서 운영 체제 개발에 C를 어떻게 사용합니까?

코드에 오류가 있는지 의심합니다 (단지 취미는 아니지만). C를 설정하는 것이 복잡 할 수 있음을 알고 있지만 이것을 처음하는 사람은 아닙니다. AFAIK, 현재 지배적 인 모든 OS는 주로 C로 작성되므로 프로세스를 설명하는 기사가 있어야합니다. 나는 또한 단계 목록에 매우 만족할 것이므로 그 단계를 위해 Google을 사용하고 조금 덜 질문을 할 수 있습니다.

참고 : 위의 C 코드와 동등한 ARM 어셈블리는 정상적으로 작동합니다. LED가 켜집니다 (약간 깜박임 후). 내 라즈베리 파이가 괜찮다고 생각합니다.


C는 Unix 용 이식 가능한 어셈블리 언어로 설계되었습니다. Linux는 C로 작성되었으므로 수행 방식을 살펴보면 상당한 시간을 절약 할 수 있습니다.
Thorbjørn Ravn Andersen

1
@ ThorbjørnRavnAndersen 나는 리눅스의 소스를 읽지 않는다고 생각한다. 리눅스는 내가 알고 싶어하는 것보다 훨씬 더 복잡하기 때문에 흥미로운 부분을 모호하게한다.
11684

1
음, 몇 개의 LED를 '연결'합니다.
11684

1
고맙지 만 대부분의 일을 직접하고 싶습니다. 학습 프로젝트입니다.
11684

1
OS를 작성하는 방법에 대한 질문을 본 적이 없다는 것을 인정해야합니다. 그리고 흥미로운 답변이 있습니다. 그것은 미친 짓이다 ...
Piotr Kula

답변:


14

몇 년 전에 아주 간단한 커널을 작성하여 386에서 실행했습니다. 몇 년 동안 베어 메탈 프로그래밍을 수행하지는 않았지만 광범위한 용어로 다음과 같은 어셈블러 코드를 작성해야합니다.

  • 부팅 과정에서 인터럽트 비활성화
  • Pi에 메모리 컨트롤러가있는 경우이를 설정해야합니다.
  • 타이머 틱을 설정
  • 인터럽트 컨트롤러 구성
  • C 코드를 실행할 수 있도록 스택 설정

스택 설정은 쉽습니다. 사용하지 않는 메모리를 찾아서 레지스터가 스택 포인터로 사용되는 주소를로드하십시오.

C 코드에서는 메모리 풀 및 스레드 테이블과 같은 OS 데이터 구조를 초기화해야합니다. C 라이브러리 함수를 사용할 수 없습니다. 직접 작성해야합니다.

간단한 멀티 태스킹 운영 체제를 작성하려면 스택에 CPU 레지스터를 저장하고 다른 스레드 스택에서 다른 레지스터 값 세트를로드하기 위해 어셈블러 루틴을 작성해야합니다. 그리고 다른 스레드를 만들려면 API를 작성해야합니다.


1
이 답변과 Georges Dupéron의 답변 중에서 선택하기가 어렵습니다. 나는 이것을 받아들이고 다른 하나는 공감했다.
11684

13

코드를 자세히 보지 않았지만 올바른 방향으로 가고있는 것 같습니다. 다음을 확인하십시오.

  • _start기호는 참으로 컴파일 및 어셈블리 파일과 C 파일을 링크 할 때 사용되는 (그리고 그 main()대신에 사용되지 않습니다)
  • 를 호출 할 때 main()C 호출 규칙을 사용해야합니다.
    • 전화 후 지시 주소를 스택에 푸시하십시오 ( returnC 주소의 진술에 의해 사용될 리턴 주소 )
    • 함수에 대한 인수를 푸시하십시오. 귀하의 경우 두 개의 32 비트 값 (총 8 바이트)을 푸시 할 수 있지만 일을 더 간단하게하기 위해 인수를 제거하고int main() { ... }
    • 반환 값을 위해 스택에 약간의 공간을 확보 할 수 있습니다.
    • 이 순서를 어떤 순서로 푸시해야하는지 기억이 안납니다
    • C 함수가 정확히 기대하는 것을 알기 위해 분해하고 ( objdump -S main.o) 스택을 조작하는 방법을 살펴보십시오.
  • 호출 규칙을 준수하지 않으면 C 컴파일러가 생성 한 어셈블리 코드가 스택의 반환 주소를 무단 변경하고 반환 주소를 푸시하지 않은 경우 반환 명령이 어딘가로 이동합니다. 로 이동하는 대신 무작위로 loop$.

OSDev 위키는 매우 유용한 ressource 것 - 그것은 주로 86 개발에 관심있어하지만 대부분의 정보는 여전히 라즈베리 파이에 적용 할 수있다.

더 많은 라즈베리 파이 osdev 관련 리소스 :


이 답변과 Steve 사이에서 선택하기가 어렵습니다. 나는 당신에게 공감대를 주었고 다른 하나를 받아 들였습니다. 5 차이점 차이를 후회합니다.
11684

OSDev 위키는 훌륭하고 특정 RasPi 자료도 있습니다
wally

2

발생할 수있는 주요 문제점은 C 라이브러리 및 프롤로그 코드입니다. 자체 코드가 실행되기 전에 시작되어 스택, 힙을 설정하고 다른 많은 유용한 작업을 수행합니다. 그러나 베어 메탈을 프로그래밍하려고 할 때 아래에 OS가 실행되지 않으므로 이러한 함수를 호출하지 않는 것이 좋습니다. 그러기 위해서는 수정 된 버전의 C 라이브러리 및 / 또는 사용자가 정의하거나 대체 한 일부 전역 기호가 필요합니다. 이 과정은 다소 복잡하기 때문에 '베이킹 파이'사람들은 튜토리얼에 어셈블리를 사용하기로 선택했습니다.


내 질문에 답변 해 주셔서 감사합니다 (늦게 답변해서 죄송합니다). 그러나 (놀랍습니다!) 저 수준의 프로세스와 관련된 비트에 대해 배우기 위해 파이를 구입했습니다 (개인 파일 / 메일 / 사진을 파괴 할 위험이있는 고가의 데스크탑에서는 그렇게하지 않을 것입니다). 스택을 설정하는 방법이나이를 설명하는 기사 / 자습서 / 일부 리소스를 추가해 주시겠습니까? (그리고 C를 실행해야 할 다른 것).
11684

2

대신 이것을 시도하십시오 :

http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

또한 x86 경험은 약간 다릅니다. 일반적인 ARM 베어 메탈 OS 프로그래밍에 적용 할 수 있습니다. 그러나 Pi의 경우 gpu가 먼저 시작되어 OS (?) 코드보다 약간 설정되었습니다.


1
좀 더 자세하게 설명하면 답변의 링크가 끊어지면 어떻게됩니까?
다스 베이더

그것은 여전히 ​​거기에 있지만 여기에 오는 사람들을 위해 구글 "베어 메탈 밸브"를 시도하고 OSDEV 시리즈를 더 잘 사용해 볼 수 있습니다. 포럼 6 개월 교차 ")
Dennis Ng

나는 이것이 더 오래된 질문에 대한 오래된 대답이라는 것을 알고 있지만 페이지 가 다운 될 경우를 대비 하여 web.archive.org 에 있습니다.
anonymoose

1

s-matyukevich/raspberry-pi-os

https://github.com/s-matyukevich/raspberry-pi-os

이 멋진 저장소는 C 부트 스트랩을 모두 수행하며 매우 복잡한 주제로 진행됩니다.

또한 Linux 커널이 어떻게 작동하는지 살펴보고 Linux 커널 코드에 주석을 달았습니다.

최소 설정에 대한 첫 번째 자습서를 살펴보십시오 : https://github.com/s-matyukevich/raspberry-pi-os/tree/43f682d406c8fc08736ca3edd08a1c8e477c72b0/src/lesson01/src

나는 그것을 강력히 추천합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.