#include <common.h>
2 #include <command.h>
3 #include <asm/io.h>
4
5 #define BCM2711_GPIO_GPFSEL0 0xFE200000
6 #define BCM2711_GPIO_GPFSEL1 0xFE200004
7 #define BCM2711_GPIO_GPFSEL2 0xFE200008
8 #define BCM2711_GPIO_GPSET0 0xFE20001C
9 #define BCM2711_GPIO_GPCLR0 0xFE200028
10 #define BCM2711_GPIO_GPLEV0 0xFE200034
11
12 #define GPIO6_9_SIG_OUTPUT 0x09240000
13 #define GPIO10_13_SIG_OUTPUT 0x00000249 //txd,rxd
14
15 void led_init(void)
16 {
17 unsigned long temp;
18 temp=readl(BCM2711_GPIO_GPFSEL0);
19 temp=temp&0x0003ffff; // ~0xfffc0000;
20 temp=temp|GPIO6_9_SIG_OUTPUT;
21 writel(temp, BCM2711_GPIO_GPFSEL0);
22
23 temp=readl(BCM2711_GPIO_GPFSEL1);
24 temp=temp&0x3ffff000;
25 temp=temp|GPIO10_13_SIG_OUTPUT;
26 writel(temp, BCM2711_GPIO_GPFSEL1);
27 }
28
29 void led_write(unsigned long led_data)
30 {
31 writel(0x3fc0, BCM2711_GPIO_GPCLR0); //led all off
32 led_data = led_data << 6;
33 writel(led_data, BCM2711_GPIO_GPSET0); //ledX on
34 }
35
36 void key_init(void)
37 {
38 unsigned long temp;
39 temp=readl(BCM2711_GPIO_GPFSEL1);
40 temp=temp&0x0003ffff;
41 writel(temp, BCM2711_GPIO_GPFSEL1);
42
43 temp=readl(BCM2711_GPIO_GPFSEL2);
44 temp=temp&0x3ffff000;
45 writel(temp, BCM2711_GPIO_GPFSEL2);
46 }
47
48 void key_read(unsigned long *key_data)
49 {
50 *key_data=(readl(BCM2711_GPIO_GPLEV0) >> 16) & 0x000000FF;
51 }
52
53 static int do_KCCI_LED(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
54 {
55 unsigned long led_data;
56 unsigned long key_data;
57 unsigned long key_data_old;
58 unsigned long i;
59 if(argc != 2)
60 {
61 cmd_usage(cmdtp);
62 return 1;
63 }
64
65 printf("*LED TEST START(PYG)\n");
66 led_init();
67 led_data = simple_strtoul(argv[1], NULL, 16);
68 led_write(led_data);
69
70 key_init();
71 do{
72 key_read(&key_data);
73 if(key_data != key_data_old)
74 {
75 if(key_data)
76 {
77 led_write(key_data);
78 puts("0:1:2:3:4:5:6:7\n");
79 for(i=0; i<8; i++)
80 {
81 if(key_data & (0x01 << i))
82 putc('O');
83 else
84 putc('X');
85 if(i!=7)
86 putc(':');
87 else
88 putc('\n');
89 }
90 putc('\n');
91 key_data_old = key_data; // 91~93 부분을 94~95 사이에 넣고 96~99 부분을 지우면 같은 결과를 가져온다.
92 if(key_data == 0x80)
93 break;
94 }
95 }
96 if(key_data==0)
97 {
98 key_data_old = 0;
99 }
100 }while(1);
101
102 printf("*LED TEST END(%#02x)\n\n", (unsigned int)key_data);
103
104 return 0;
105 }
106
107 U_BOOT_CMD(led, 2, 0, do_KCCI_LED, "kcci LED Test", "number - Input argument is only one.(led [0x00~0xff])\n");
위 파일은 ~/pi_bsp/u-boot/common 에 있는 cmd_kcci_led.c 파일이다
이 내용은 u-boot에서 ./build.sh를 통해 bin 파일을 만들고 라즈베리파이의
/boot/firware에 넣으면 부팅할 때 위 내용으로 부팅된다
이상으로 부트로더는 끝이다
~$ uname -a // 커널 정보를 all 가져오는 것
현재 6.1.0 버전이다
우분투에서
~$ cd pi_bsp/
~/pi_bsp$ mkdir kernel ; cd kernel
~/pi_bsp/kernel$ sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev
~/pi_bsp/kernel$ sudo apt install crossbuild-essential-armhf
~/pi_bsp/kernel$ git clone --depth=1 -b rpi-6.1.y https://github.com/raspberrypi/linux
~/pi_bsp/kernel$ cd linux
디렉토리 개수
깊이를 1로 해서 찾기
파일+디렉토리 개수
~/pi_bsp/kernel$ tar cvf linux.tar linux
1.7기가 폴더를 하나로 묶는 것
c : create
v : 진행상황
f : 파일
압축푸는 것
~/pi_bsp/kernel$ gzip linux.tar
-d : 풀기
묶음 풀기
~/pi_bsp/kernel$ tar xvf linux.tar linux
-x : 풀 때
bzip이 gzip보다 압축률이 높다
파일이 클수록 비용이 많이 든다
대신 시간이 오래 걸린다
다 하면 이렇게 됨
이제 linux 폴더로 들어가서
~/pi_bsp/kernel/linux$ cd arch/arm/configs/
~/pi_bsp/kernel/linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig
.config 수정하는 법
~/pi_bsp/kernel/linux$ make ARCH-arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
~/pi_bsp/kernel/linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j4
커널 이미지는 zimage이다
modules : 디바이스 드라이브
dtbs 디바이스 드라이브 정보가 담긴 것들
위의 defconfig를 make 안하고 zImage를 make하면 안된다
리눅스는 운영체제 이름이기도 하지만 커널이라는 이름을 한번 더 쓴다
다양한 어플리케이션을 포함하는 배포판이다
유닉스 윈도우즈 리눅스 타이젠 등...
컴퓨터 시스템의 전반적인 동작을 제어하고 조정하는 시스템 프로그램들의 집합
하드웨어와 응용 프로그램 간의 인터페이스 역할
CPU, 주기억 장치, 입출력 장치 등의 컴퓨터 자원을 관리
bash shell이 응용프로그램을 실행시킴
하드웨어를 제어하는 것이 디바이스 드라이브
임베디드 리눅스
make를 하다가 오타가 많아서 build.sh에 넣어놓았다.
linux에서 ./build.sh를 실행하면 된다
디바이스 드라이브는 /lib/modules 에 만들어진다
잘못 설치하면 문제가 많으므로 lcd를 분해해서 옮기기로 함
SD카드를 윈도우에 연결 후
우분투에서 연결해준다
$ df
/dev/sdb1 261108 75820 185288 30% /media/ubuntu/bootfs
/dev/sdb2 30322460 15917604 13048344 55% /media/ubuntu/rootfs
~/pi_bsp/kernel/linux$ sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=/media/ubuntu/rootfs modules_install
~/pi_bsp/kernel/linux$ sudo cp /media/ubuntu/bootfs/kernel7l.img /media/ubuntu/bootfs/kernel7l-backup.img
~/pi_bsp/kernel/linux$ sudo cp arch/arm/boot/zImage /media/ubuntu/bootfs/kernel7l.img
~/pi_bsp/kernel/linux$ sudo cp arch/arm/boot/dts/*.dtb /media/ubuntu/bootfs/
~/pi_bsp/kernel/linux$ sudo cp arch/arm/boot/dts/overlays/*.dtb* /media/ubuntu/bootfs/overlays/
~/pi_bsp/kernel/linux$ sudo cp arch/arm/boot/dts/overlays/README /media/ubuntu/bootfs/overlays/
~/pi_bsp/kernel/linux$ sudo vi /media/ubuntu/bootfs/config.txt //제일 아래 추가
------------
arm_64bit=0
------------
arm용을 ubuntu에서 하는 것이므로 조심해야한다
ko : kernel object
위 내용 다 하고 sync 명령 or eject 후 뽑는다
~$ sudo vi /boot/config.txt
sync 후 재부팅한다
커널 변경된 것이 보인다
마지막으로 디바이스 드라이브가 잘 왔는지 본다
lsmod로 모듈들이 있는 것을 확인했다.
이미지를 하나 준비한다
cat.jpg
800x480이상으로 준비할 것
kernel에 옮겨온다
~/pi_bsp/kernel$ eog cat.jpg // 우분투 cli 창 열어서 직접 치면 사진을 볼 수 있음
~/pi_bsp/kernel$ sudo apt install gimp -y
~$ gimp // 우분투 cli에서 열어야 함
이후 file - open - cat.jpg 에서 열면
이런식으로 된다
한글설정
settings - region & language - manage installed languages - 설치
한국어가 제일 위에 위치하도록
시스템 전체 적용 하면 이제 한글이 잘 된다
사진 우클릭 - 이미지 - 변형 - 회전한다(안해도 됨)
사진 우클릭 - 이미지 - 이미지 비율 조정
800에 480으로 변경하는데 오른쪽 부분에 연결부분을 끊어야 아래가 변경된다
파일 - export as... - ppm - ascii
~/pi_bsp/kernel$ sudo apt install netpbm
~/pi_bsp/kernel$ pnmquant -fs 224 cat.ppm > logo_kcci_224.ppm
~/pi_bsp/kernel$ pnmnoraw logo_kcci_224.ppm > logo_kcci_clut224.ppm
~/pi_bsp/kernel$ cp logo_kcci_clut224.ppm linux/drivers/video/logo/
makefile : 소스파일 명시
kconfig : make에 사용된 define
~/pi_bsp/kernel$ vi linux/drivers/video/logo/Kconfig
넣어준다
~/pi_bsp/kernel$ vi linux/drivers/video/logo/Makefile
마찬가지로 넣어준다
~/pi_bsp/kernel$ vi linux/drivers/video/logo/logo.c
여기에 부트로고 바꾸는 내용 추가로 넣어야 함
~/pi_bsp/kernel/linux$ make ARCH-arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
Devicd Drivers -> GPIO Support에서 체크된 두개를 지운다 -> 지우면 화면 안보임
user level - cli 창
시스템 콜 함수 등록
~/pi_bsp/kernel/linux$ vi include/uapi/asm-generic/unistd.h
추가, 수정 해준다
~/pi_bsp/kernel/linux$ vi arch/arm/tools/syscall.tbl
추가 해준다
~/pi_bsp/kernel/linux$ vi include/linux/syscalls.h
추가 해준다
~/pi_bsp/kernel/linux/kernel$ vi test_mysyscall.c
#include <linux/kernel.h>
asmlinkage long sys_mysyscall(long val)
{
printk(KERN_INFO "Welcome to KCCI's Embedded System!! app value=%ld\n", val);
return val*val;
}
~/pi_bsp/kernel/linux/kernel$ vi Makefile
그리고
~/pi_bsp/kernel/linux/kernel$ cd ..
~/pi_bsp/kernel/linux$ ./build.sh
실행한다
오류가 나면 -j4를 제외하고 다시한다
코어 4개가 스레드로 돌아서 찾기 힘들었지만 하나로 하면 찾을 수 있다
~/pi_bsp/kernel/linux$ cp arch/arm/boot/zImage /srv/nfs/
우분투에서 옮기고
/mnt/ubuntu_nfs$ sudo cp zImage /boot/firmware/kernel7l.img
/mnt/ubuntu_nfs$ sync
라즈베리에서 적용한다
mkdir systemcall_test ; cd systemcall_test
그리고 공유폴더에 있는 파일을 가져와서 넣는다
#include <stdio.h>
#include <unistd.h>
#include <asm-generic/unistd.h>
#pragma GCC diagnostic ignored "-Wunused-result"
int main()
{
long i;
printf("input value = ");
scanf("%ld",&i);
i = syscall(__NR_mysyscall,i);
if(i<0)
{
perror("syscall");
return 1;
}
printf("mysyscall return value = %ld\n",i);
return 0;
}
~/systemcall_test$ cp /srv/samba/systemcall_app.c
이것은 비표준이라 gcc하면 에러가 난다
헤더파일을 라즈베리에 전송해야한다
~/pi_bsp/kernel/linux$ cp include/uapi/asm-generic/unistd.h /srv/nfs/
우분투에서 전송 후
~/systemcall_test$ cd /usr/include/asm-generic
/usr/include/asm-generic$ mv /mnt/ubuntu_nfs/unistd.h .
/usr/include/asm-generic$ cd ~/systemcall_test
~/systemcall_test$ gcc syscall_app.c -o syscall_app
~/systemcall_test$ ./syscall_app
5
dmesg - 원형 queue에 있는 내용 가져오기
맨 마지막에 Welcome~~ 하면서 나온다
#pragma : 컴파일 옵션을 알려주는 전처리기
file syscall_app
cp -r systemcall_test/ /mnt/ubuntu_nfs
mv /srv/nfs/syscall_test .
cd syscall_test
arm-linux-gnueabihf-gcc syscall_app.c -o syscall_app
/usr/local$ sudo apt install locate