http://muosys.egloos.com/l2
'리눅스커널 > Device Driver' 카테고리의 다른 글
[charger] bq2415x (0) | 2017.06.12 |
---|---|
PS/2 키보드 LED제어 (0) | 2015.05.13 |
문자디바이스 드라이버와 file_operations (0) | 2015.05.12 |
IOCTL (0) | 2015.05.12 |
디바이스드라이버기초정리 (0) | 2015.05.11 |
http://muosys.egloos.com/l2
[charger] bq2415x (0) | 2017.06.12 |
---|---|
PS/2 키보드 LED제어 (0) | 2015.05.13 |
문자디바이스 드라이버와 file_operations (0) | 2015.05.12 |
IOCTL (0) | 2015.05.12 |
디바이스드라이버기초정리 (0) | 2015.05.11 |
학교에서 수업때 배운 내용이지만 다시봐도 새롭다.
쟈료를 가지고 따라가보겠다.
- PS/2 제어 레지스터
PS/2 는 8042 라고 하는 컨트롤러가 제어한다. 이것음 다음과 같은 I/O주소를 갖는다.
PORT READ/Write Function
0x60 Read Read Input Buffer
0x60 Write Write Output Buffer
0x64 Read Read Status Register
0x64 Write Send Command
PS/2 키보드를 제어하기위해 컨트롤러에 명령을 써야 하는데 이때 사용하는 레지스터가 0x64번지 이다.
이번지에 명령을 쓴다. 즉 위의 Send Command 레지스터에 써 넣는다.
- 0xEE : 에코 요청 명령
- 0xED: 키보드에 있는 LED를 끄거나 키기 위한 명령
키보드에 읽을데이터가 있는가 확인할때는 0x64를 읽으면 된다.
PC 에서 키보드 데이터를 써 넣었다면 8042 입장에서는 input 이므로 비트 0번이 1이된다.
데이터를 써 넣기 전에 비트 0번이 1이 아닌가를 확인하고 써 넣어야 한다.
---키보드 응답 또는 전송 데이터 읽기
1) 0x64번지의 읽은 값의 비트1을 읽어 1이 될때까지 기다린다.
2) 0x60번지를 읽으면 키보드에서 전송한 데이터를 읽을 수 있다.
이때 0x64번지를 읽는 과정에서 문제가생겨 무한루프에 빠지지 않도록 다음과 같이 구현한다.
u8 ps2_key_read_data(void)
--명령 전송 및 응답 데이터 읽기
1) 0x64 번지에 명령을 써 넣는다.
2) 0x64 번지를 읽어 비트 0이 0이 될때까지 기다린다.
3) 0x64 번지를 읽어 비트 1이 1이 될때까지 기다린다.
키보드가 명령을 받으면 응답데이터를 보내므로 이 값을 얻기위해서 이다.
4) 0x60 번지를 읽으면 키보드에 전송한 데이터를 읽을 수 있다.
LED를 키려변 1로 셋한다
0비트 : SCROLL LOCK
1비트 : NUM LOCK
2비트 : CAPS LOCK
if(0xFA != ps2_key_exchange_data(0x01)) return 0;
-버퍼 클리어
참고 : B004_다중 소스 모듈과 PS2키보드 - 유영창
[charger] bq2415x (0) | 2017.06.12 |
---|---|
USB 인사이드 muosys.egloos.com (0) | 2016.05.16 |
문자디바이스 드라이버와 file_operations (0) | 2015.05.12 |
IOCTL (0) | 2015.05.12 |
디바이스드라이버기초정리 (0) | 2015.05.11 |
IT EXPERT 의 리눅스 디바이스 드라이버 -유영창 - 을 읽으며 정리해 보았다.
문자디바이스 드라이버의 특성 바이트 단위로 처리되고, 써넣는 데이터는 보존될 수도 , 보존되지 않을 수도 있다.
문자 디바이스 드라이버의 경우
char_dev.c
/usr/src/linux-4.0.2/include/linux/fs.h
/usr/src/linux-4.0.2/include/linux/types.h"
typedef long long __kernel_loff_t; // 8byte 32bit system #if defined(__GNUC__) |
struct module *owner;
- 파일 오퍼레이션의 소유자를 나타낸다. 디바이스 드라이버의 사용 횟수를 커널에서 관리해야 하기 때문에 이 필드를 지정한다. 보통은 THIS_MODULE을 지정한다.
ssize_t (*aio_read) (
struct
kiocb *,
const
struct
iovec *, unsigned
long
, loff_t);
- 디바이스 드라이버의 비동기 읽기를 구현하는 함수를 지정한다. 일반적인 디바이스 드라이버에서는 이 기능을 사용하지 않기 때문에 NULL을 지정한다.
문자디바이스 드라이버를 동작하려면 커널에 등록되어 있어야한다.
<linux/fs.h> 헤더파일을 소스에 포함 시켜야 한다.
- register_chrdev : 디바이스를 등록한다.
- unregister_chrdev:등록된 디바이스를 제거한다.
/usr/src/linux-4.0.2/include/linux/fs.h"
USB 인사이드 muosys.egloos.com (0) | 2016.05.16 |
---|---|
PS/2 키보드 LED제어 (0) | 2015.05.13 |
IOCTL (0) | 2015.05.12 |
디바이스드라이버기초정리 (0) | 2015.05.11 |
platform_driver (0) | 2015.04.23 |
아직멀었구나..
괜히 최신커널쓴다고 오류만 난발.
오늘도 에러가..
문자 디바이스 드라이버 구조체중에 ioctl()함수가 사라지고 이두개를 사용한다고 한다.
.unlocked_ioctl or .compat_ioctl 로 사용!
세부정보 : http://forum.falinux.com/zbxe/?document_srl=563022 FF포럼
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
인자만 한개 지워주니깐 성공. 휴.
세부사항은 검색 하십쇼!
디바이스 예제. //ioctl.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
int kw_device_open(struct inode *inode, struct file *filp)
{
printk(KERN_ALERT "kw_device open fuction called\n");
return 0;
}
int kw_device_release(struct inode *inode, struct file *filp)
{
printk(KERN_ALERT "kw_device release fuction called\n");
return 0;
}
//ioctl 연산 구현 부분 기존 read, write연산 제거하고 모두 ioctl로 구현
int kw_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
//변형{
switch(cmd)
{
case 1: //read
printk(KERN_ALERT "ioctl read...\n");
break;
case 2: //write
printk(KERN_ALERT "ioctl write...\n");
break;
default:
printk(KERN_ALERT "ioctl unknown command...\n");
break;
}
return 0;
}
//동작만 살펴보기 위해 간단한 메세지만 출력하 였다.
static struct file_operations vd_fops ={
.owner = THIS_MODULE,
.open = kw_device_open,
.release = kw_device_release,
.unlocked_ioctl = kw_device_ioctl //변형부분!
};
int __init kw_device_init(void){
// 문자 디바이스를 등록한다.
if(register_chrdev(250,"kw_device", &vd_fops) <0 )
printk(KERN_ALERT "driver init failed\n");
else
printk(KERN_ALERT "driver init successful\n");
return 0;
}
void __exit kw_device_exit(void){
unregister_chrdev(250,"kw_device");
printk(KERN_ALERT "driver cleanup successful!\n");
}
module_init(kw_device_init);
module_exit(kw_device_exit);
MODULE_LICENSE("GPL");
응용프로그램 //ioctl_app
파일 첨부..
책: 리눅스 커널 프로그래밍(한빛) 에서
소스작성중.
USB 인사이드 muosys.egloos.com (0) | 2016.05.16 |
---|---|
PS/2 키보드 LED제어 (0) | 2015.05.13 |
문자디바이스 드라이버와 file_operations (0) | 2015.05.12 |
디바이스드라이버기초정리 (0) | 2015.05.11 |
platform_driver (0) | 2015.04.23 |
리눅스버전 3.19.4
커널에 자원 처리를 요청하는 방법은 시스템 호출 과 파일입출력을 이용하여 드바이스 드라이버를 사용하는 방식
/usr/src/linux-3.19.4/include/linux/types.h 의
15 typedef __kernel_dev_t dev_t;12 typedef __u32 __kernel_dev_t;
진입점 (entry point, entrance) IT용어사전, 한국정보통신기술협회
진입점 [entry point, entrance, 進入點] (용어해설)
1. 어떤 프로그램이나 서브루틴의 시작주소. 즉 제어를 서브루틴으로 옮기기 위해 분기하는 주소이다.
2. 어떤 서브루틴을 호출 했을 때 그 안에서 제일 먼저 실행되는 명령어
/usr/src/linux-3.19.4/Documentation$ vim devices.txt
linux-3.19.4/include/uapi/linux/major.h 에 디바이스에대한 major 즉 주번호 들이 정의되어 있다.
실제 사용중인 주번호는 "cat /proc/devices" 를 통해서 확인 가능
root@li:/usr/src/linux-3.19.4/include/uapi/linux# cat /proc/devices
Block devices: |
참고
리눅스 디바이스 드라이버-유영창
심볼 테이블 http://kirari83.tistory.com/entry/EXPORTSYMBOL
플랫폼디바이스 드라이버 http://blog.naver.com/sigsaly/100102042663
USB 인사이드 muosys.egloos.com (0) | 2016.05.16 |
---|---|
PS/2 키보드 LED제어 (0) | 2015.05.13 |
문자디바이스 드라이버와 file_operations (0) | 2015.05.12 |
IOCTL (0) | 2015.05.12 |
platform_driver (0) | 2015.04.23 |
PNP 기능을 플랫폼 드라이버라는 형태로 지원한다.
드라이버의 기본동작을 구현하기 위한 자료구조체
/usr/src/linux-3.19.4/include/linux/platform_device.h
174 struct platform_driver {
490 #define PLATFORM_NAME_SIZE 20
보통 사용 예 static struct platform_driver test_driver= { .probe = test_probe, .remove= test_remove, .suspend= test_suspend .resume = test_resume, .driver ={ .name = TEST_DEVICE_DRIVER_NAME, }, }; |
플랫폼 드라이버 구조체 정보는 다음과 같은 함수로 커널에 등록되거나 제거된다.
platform_driver_register() 함수는 : pdev 정보를 커널 내부에 등록하기 위해서 사용되므로 보통 모듈 초기화 함수에서 사용된다. 반환값이 0이면 정상이다.
32 #ifdef MODULE |
다른버전 ----4.0.2
/usr/src/linux-4.0.2/drivers/base/platform.c
참조 : B003_디바이스 드라이버 모듈 (유영창)
USB 인사이드 muosys.egloos.com (0) | 2016.05.16 |
---|---|
PS/2 키보드 LED제어 (0) | 2015.05.13 |
문자디바이스 드라이버와 file_operations (0) | 2015.05.12 |
IOCTL (0) | 2015.05.12 |
디바이스드라이버기초정리 (0) | 2015.05.11 |
리눅스 커널 컴파일을 해보자 .
테스트사양 ubuntu-14.04.2 메모리 2GB 프로세스2개
커널을 받기위해 사이트를 접속한다.
커널 소스는 보통 /usr/src 폴더에 보관한다?
받은 소스를 /usr/src폴더에 옮긴후 다운받은 압축파일을 풀어헤친다
터미널 창에서 root@li:/usr/src# tar xvf linux-3.19.4.tar.xz
압축을 풀고 cd linux-3.19.4
1. apt-get install ncurses-dev (필요한 패키지를 설치한다.)
커널 컴파일하기전에 /boot/config-3.16.0-30-generic 커널 설정파일을 .config파일로 옮긴다.
cp config-3.16.0-30-generic /usr/src/linux-3.19.4/.config
2. make menuconfig (커널 관련 설정파일을 설정하는 부분)
Load (선택) 방금복사한 파일 .config (OK) Save 세이브한다.
통합 커널 컴파일 할수있는 툴을 설치한다.
추가 apt-get update
3. apt-get install kernel-package
4. make-kpkg -j8 --initrd --revision=1.0 kernel_image
(revision= 버전)생성될 파일의 버전을 의미한다. -j 옵션 프로세스 *2(멀티컴파일? CPU를 여러개사용하여 컴파일 빠르도록)
현재시각 16시 29분 ( 프로세스가 4개이므로 *2인 옵션에 8)
결과사진
상위폴더에 cd ../
linux-image-3.19.4_1.0_amd64.deb 파일이 생성 되었는지 확인
5. dpkg -i linux-image-3.19.4_1.0_amd64.deb
/boot 및 /lib/modules 에 파일이 추가된다
6. reboot now
7. uname -a (커널 버전이 바뀌었는지 확인한다.
과거 컴파일시
make -j8 아키텍쳐 부트 폴더의 bzImage 를 boot에 vmlinux-XXX로 복사 update-initramfs -c -k 2.6.29 Sudo update-grub |
이상 쉬엇!
LCD (1) (1) | 2016.06.23 |
---|---|
ARM 리눅스 커널 3.0 포팅(Porting the Linux kernel 3.0 for ARM Architecture) (0) | 2016.06.23 |
시스템콜 (0) | 2015.04.16 |
systemcall (0) | 2015.04.15 |
스와퍼(Swapper)프로세스 (0) | 2015.04.15 |
시스템 콜은 응용프로그램에서 운영체제에게 어떠한기능(시스템 자원)을 수행해 달라고 하는 하나의 수단이다.
- 저수준 프로그래밍을 몰라도 프로그래밍 가능, 프로그램 호환성이 좋다.
- 사용자 요청을 처리하기전에 인터페이스 수준에서 올바른 요청인지 검사할 수 있으므로 시스템 보완성이 높다.
시스템 콜의 종류 - type 별로 구분
- 프로세스 제어
- 파일조작
- 장치 관리
- 시스템 정보 및 자원 관리
- 통신관련
- 시스템콜의 초기화는 시스템 부팅시 커널 초기화 과정에서 trap_init()함수 내의 set_system_gate(SYSCALL_VECTOR, &system_call)을
수행해서 0x80 인터럽트를 위한 게이트 디스크립터를 설정
메모리 주소 영역이 커널 주소영역 과 사용자 주소영역 으로 구분되어있기 때문에, 사용자 프로세스에서 커널 영역에
접근시 Segmentation Fault 메시지를 출력하면서 프로세스가 종료된다. (커널 스레드나 디바이스드라이버 계층만 접근가능)
arm 은 SWI 명령을 사용하면 내부 인터럽트가 발생한다.
x86에서는 eax에 시스템 콜 번호를 넣고 0x80번 인터럽트를 발생시킨다.
ARM의 경우
-- USER 모드의 태스트에서 SWI 명령을 사용해서 특권모드인 SVC 모드로 진입하고, SWI 핸들러는 SWI 명령의 인자로 넘어오는 시스템 콜 번호를 보고서 어떻게 동작할지 결정한다.
그림[1] 시스템 콜
[그림2] 시스템 콜 함수 찾아가는 과정
음.. fork()함수를 썻을때 glibc라이브러리를 통해 vfork()로 연결되는 부분을 찾고싶은데????????........어떻게하지
일단 라이브러리 소스를 받아보았다.. 졸려...............퓨ㅜ
[그림3] ARM 에서의 시스템콜 호출순서를 보자
1. 사용자 프로세스에서 fork를 호출
2. glibc에 래핑되어 있는 fork함수가 호출되어 vfork함수를 호출한다. swi __NR_vfork 명령으로 시스템 콜을 호출하면
3. exception vector table로 들어간다(커널영역)
(fork()의 시스템 콜 번호가 0x02 므로 여기에 4를 곱해 ,해당 시스템 콜을 처리하는 함수의 주소가
System Call Vector Table의 어느 위치에 있는지 계산)
4. sys_fork() 함수로 분기
glibc - GNU C library 의 약자. GNU 시스템과 Linux에서 사용되는 대표적인 C라이브러리 |
glibc받기
http://www.gnu.org/software/libc/
참고
- 12장 시스템 콜 구현하기(도전 임베디드 OS만들기 [이만우])
- 휴인스 쟈료 www.huins.com
- 리눅스 커널기초 http://idkkangjs.blog.me/30091117058
- ARM 아키텍쳐 http://www.jkelec.co.kr/img/lecture/arm_arch/arm_arch_3.html
- FALinux Forum [커널산책]
http://forum.falinux.com/zbxe/index.php?document_srl=575411
ARM 리눅스 커널 3.0 포팅(Porting the Linux kernel 3.0 for ARM Architecture) (0) | 2016.06.23 |
---|---|
커널컴파일 (0) | 2015.04.17 |
systemcall (0) | 2015.04.15 |
스와퍼(Swapper)프로세스 (0) | 2015.04.15 |
schedule()함수 (0) | 2015.04.15 |
스템콜 추가
asmlinkage : 어셈블리 언어로 구현된 함수에서 호출될 때 사용하는 keyword
arch/x86/kernel/syscall_table_32.S
최신커널 : /arch/x86/syscalls/syscall_*.tbl
1 ENTRY(sys_call_table) 339 .long sys_bit /* 337 */ //새로 추가 |
어셈블러 지시자들 (자세한 내용은 아래 asm 링크 참고)
/usr/src/linux-2.6.32.65/arch/x86/include/asm/unistd_64.h
최근 /arch/x86/syscalls/syscall_*tbl
134 #define __NR_clone 56
664 #define __NR_bit 299
#define NR_syscalls (__NR_syscall_max + 1) --> 따라가서 변경 ///usr/src/linux-2.6.32.65/include/asm/asm-offsets.h |
ARM
/usr/src/linux-2.6.32.65/arch/arm/include/asm/unistd.h
시스템 콜 번호를 정의한다.
/usr/src/linux-2.6.32.65/include/linux/syscalls.h
kernel 에 소스추가 및 Makefile 에 파일 추가
작성 후 Makefile 에 소스 추가 및 재 컴파일 한다.
함수추가는 : /include/linux/syscalls.h
어플리케이션에서 시스템 콜 호출
--------------------------------------------------------------------
신규버전
참고
asm : http://korea.gnu.org/manual/release/as/as-ko_7.html
KLDP : http://kldp.org/node/91565
linux system call 의 호출 구조 http://www.hanbit.co.kr/network/view.html?bi_id=1062 저자 : 서민우 출처: Embedded World
커널컴파일 (0) | 2015.04.17 |
---|---|
시스템콜 (0) | 2015.04.16 |
스와퍼(Swapper)프로세스 (0) | 2015.04.15 |
schedule()함수 (0) | 2015.04.15 |
프로세스1-3 (0) | 2015.04.14 |