내 rootfs.cpio에는 다음 파일만 있습니다.
[root@localhost extract]# ls
dev init tmp
개발자에게는 콘솔만 있습니다.
init는 마지막에 제공된 프로그램에서 크로스 컴파일됩니다.
그런 다음 이미지를 만들고 Linux를 실행합니다. 정상적으로 실행되지만 init가 실행되면 다음과 유사한 오류가 표시됩니다.
Failed to open /sys/class/gpio/gpio251/direction
Failed to open /sys/class/gpio/gpio251/value
그래서 이러한 폴더와 파일을 수동으로 만들었고 이제 다음과 같이 보입니다.
[root@localhost extract]# ls
dev init tmp sys
sys 내부에서 필요한 폴더와 파일(비어 있음)을 만들었습니다.
그러나 그런 경우에도 코드가 실행되지 않고 커널 패닉이 발생합니다.
배경
이 코드는 Linux 시스템에 필요한 모든 디렉터리를 포함하는 전체 파일 시스템에서 가져왔습니다. 이 코드를 별도로 크로스 컴파일하고 이름을 init로 바꿨습니다.
작동할 것으로 예상합니다(예: LED 켜기).
또 다른 방법
bash> echo 240 > /sys/class/gpio/export
bash> echo out > /sys/class/gpio/gpio240/direction
bash> echo 1 > /sys/class/gpio/gpio240/value
이 방법은 설명되어 있습니다GPIO 드라이버. 따라서 이러한 필수 파일을 수동으로 생성하고 크로스 컴파일한 후 이름을 init로 바꿉니다. 그런 다음 rootfs.cpio를 만들고 OS 이미지를 만듭니다. 하지만 그것도 작동하지 않습니다.
질문 내 파일 시스템(일부)에서 코드가 올바르게 실행되지 않는 이유는 무엇입니까?
코드가 다른 파일이나 동적 라이브러리(전체 파일 시스템에 존재)에 의존합니까? 수동으로 생성된 파일이 작동하지 않는 이유는 무엇입니까?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
int main( )
{
extern char *optarg;
char *cptr;
int gpio_value = 0;
int nchannel = 0;
int c;
int i;
opterr = 0;
int argc=5;
char *argv;
char *argv2[] = {"gpio-demo", "-g", "255", "o", "0"}; argv = argv2;
while ((c = getopt(argc, argv, "g:io:ck")) != -1) {
switch (c) {
case 'g':
gl_gpio_base = (int)strtoul(optarg, &cptr, 0);
if (cptr == optarg)
usage(argv[0]);
break;
case 'i':
gpio_opt = IN;
break;
case 'o':
gpio_opt = OUT;
gpio_value = (int)strtoul(optarg, &cptr, 0);
if (cptr == optarg)
usage(argv[0]);
break;
case 'c':
gpio_opt = CYLON;
break;
case 'k':
gpio_opt = KIT;
break;
case '?':
usage(argv[0]);
default:
usage(argv[0]);
}
}
if (gl_gpio_base == 0) {
usage(argv[0]);
}
nchannel = open_gpio_channel(gl_gpio_base);
signal(SIGTERM, signal_handler); /* catch kill signal */
signal(SIGHUP, signal_handler); /* catch hang up signal */
signal(SIGQUIT, signal_handler); /* catch quit signal */
signal(SIGINT, signal_handler); /* catch a CTRL-c signal */
switch (gpio_opt) {
case IN:
set_gpio_direction(gl_gpio_base, nchannel, "in");
gpio_value=get_gpio_value(gl_gpio_base, nchannel);
fprintf(stdout,"0x%08X\n", gpio_value);
break;
case OUT:
set_gpio_direction(gl_gpio_base, nchannel, "out");
set_gpio_value(gl_gpio_base, nchannel, gpio_value);
break;
case CYLON:
#define CYLON_DELAY_USECS (10000)
set_gpio_direction(gl_gpio_base, nchannel, "out");
for (;;) {
for(i=0; i < ARRAY_SIZE(cylon); i++) {
gpio_value=(int)cylon[i];
set_gpio_value(gl_gpio_base, nchannel, gpio_value);
}
usleep(CYLON_DELAY_USECS);
}
case KIT:
#define KIT_DELAY_USECS (10000)
set_gpio_direction(gl_gpio_base, nchannel, "out");
for (;;) {
for (i=0; i<ARRAY_SIZE(kit); i++) {
gpio_value=(int)kit[i];
set_gpio_value(gl_gpio_base, nchannel, gpio_value);
}
usleep(KIT_DELAY_USECS);
}
default:
break;
}
close_gpio_channel(gl_gpio_base);
return 0;
}
답변1
/sys
특수 파일 시스템입니다. 그냥 만들어서 파일을 넣을 수는 없습니다. /proc
커널이 제공하는 가짜 파일 시스템 과 같습니다 .
시작하려면 두 가지가 필요합니다 /sys
.
- 커널 구성에는
CONFIG_SYSFS=y
. - 당신은 그것을 설치해야합니다
mount -t sysfs none /sys
(당신이 언급한 이후 initramfs에서 실행 중이라고 가정cpio
).
따라서 디렉토리 자체가 거기에 있어야 마운트할 수 있지만 그게 전부이고 그 안에는 아무것도 없습니다.