Let’s go!

  • 곽재식의 세균 박람회

    곽재식의 세균 박람회

    isbn: 9788934992349

    곽재식이 파토에서 끊임없이 말하는 이상한 재주를 가진 아저씨로 알고 있었는데, 이런 책도 썼다. 직업이 소설가임을 몰랐다. 책 내용을 보고 예측한대로 화학을 배웠다. 이 책이 작가 성격대로 글이 쉽고 길다.

    다른 사람에게 사실을 이해시키려면 핵심만 말해서는 안된다. 우리가 수학 공식만 보고 이해했다고 할 수 없다. 사람이 이렇게 쉽게 이해할 수 있다면 대부분 출판사가 망했다고 본다. 이런 점을 노렸는지 글이 길지만 어렵지 않고 쉽게 읽힌다. 정말 쉽게 쓰려 노력했지만 반면에 잡다한 지식이 많다.

    작가 시점으로 세균을 바라보면 지구는 연결되어 있다. 우리 모두 공통 조상을 가지고 있다. 인종 차별은 말도 안되고, 동식물, 균류, 세균도 모두 같은 동족이라 본다. 어떻게 보면 DNA에 정보를 어떻게 저장, 전달하냐에 따라 인류 삶이 변했다. 인류는 이미 스케일이 다른 정보화 사회를 겪었다.

    지금 인류가 유전자가 결정하는 수동적, 우연적 삶을 산다. 유전자 가위가 발명한 지금 우리가 능동적, 의도적으로 유전자를 결정할 수 있을까? 40억년까지 자연이 결정했지만, 지금이 우리가 자연을 결정하는 중요한 시점일지도 모른다. 나중에 우리가 스스로 새로운 종이라고 선언하는 날이 있다면, 여러 중요한 기술 중 하나가 유전자 가위라고 본다.

  • xbox 360 드라이버 만지기1

    xbox 360 드라이버 만지기1

    내 라즈베리 파이에 usb 타입 xbox360 패드를 붙여 보고싶다. 리눅스 커널 xpad.c에 마이크로소프트 거의 모든 제품 usb vendor, product id가 등록되어 있다. xpad.c가 조금 복작하여 usb 인터럽트 사용 방법을 잘 이해할 수 없다. 키 입력 설정을 어떻게 할지는 나중 문제고… usb-skeletion.c 문서 역시 어렵다. 여기는 인터럽트 대신 대용량 데이터 전송을 목표로 했다.

    그 중 가장 비슷한 usb 마우스 드라이버를 커널에서 찾았다. 커널이 성경과 같아 모든 물음에 대한 답을 한다. 200줄 약간 넘어가는 코드로 정말 인터럽트 핵심만 작성했다.

    대략 구성은 아래와 같이 된다.

    • usb 구조체 선언.
    • 사용가능한 usb 번호 찾음, 등록.
    • 입력 설정.
    • 인터럽트 설정.

    usb_fill_int_urb로 call 함수를 등록하여 인터럽트를 사용하면 된다. usb 인터럽트가 일정 주기로 발생한다. 계속 실행하기 위해 인터럽트로 실행할 함수 안에 usb_submit_urb를 넣는다. 알고보면 참 쉬운데 처음 이해하기 어렵다. xpad.c도 같은 방식이다. 처음에 왜 안보였는지…아직 키 입력을 설정하지 않았고, 커널에 test를 출력하도록 했다.

    usb 구조체는 여러 정보를 쉽게 사용하려 군더더기를 많이 붙이는 듯 하다.

    #include <linux/kernel.h>
    #include <linux/input.h>
    #include <linux/module.h>
    #include <linux/usb/input.h>
    #include <linux/init.h>
    #include <linux/device.h>
    #include <linux/usb/input.h>
    #include <linux/slab.h>
    #define USB_XBOX_MINOR_BASE	1
    		
    //구조체 선언.
    struct usb_xpad{
    	struct input_dev *dev;		/* input device interface */
    	struct usb_device *udev;	/* usb device */
    	struct usb_interface *intf;	/* usb interface */
    	__u8    irq_in_endpointAddr;    /* interrupt in address*/
    	__u8    irq_out_endpointAddr;   /* interrupt out address*/
    	struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
    	signed char *data;		/* input data */
    	struct urb *irq_in;		/* urb for interrupt in report*/
    	struct work_struct work;	/* init/remove device from callback */
    };
    static struct usb_xpad *myPad;
    static int xpad_init_input(struct usb_xpad *xpad);
    static void xpad_deinit_input(struct usb_xpad *xpad);
    static void usb_xpad_irq(struct urb *urb){
    	pr_info("test\n");
    	usb_submit_urb(urb, GFP_KERNEL);
    }
    static int xpad_init_urb(struct usb_interface *intf, struct usb_xpad *xpad);
    static ssize_t xbox_read(struct file *file, char *buffer, size_t count,
    			 loff_t *ppos)
    {
    	pr_info("device was read.\n");
    	return 0;
    }
    static ssize_t xbox_write(struct file *file, const char *user_buffer,
    			  size_t count, loff_t *ppos)
    {
    	return 0;
    }
    static int xbox_open(struct inode *inode, struct file *file)
    {
    	int retval;
    	struct urb *ptr_urb;
    	ptr_urb = usb_alloc_urb(0, GFP_KERNEL);
    	pr_info("device was opened.\n");
    	if (!ptr_urb) {
    		retval = -ENOMEM;
    		goto error;
    	}
    	return 0;
    error:
    	if(ptr_urb)
    	{
    		usb_free_urb(ptr_urb);
    	}
    	return retval;
    }
    static int xbox_release(struct inode *inode, struct file *file)
    {
    	pr_info("xbox was released\n");
    	return 0;
    }
    static int xbox_flush(struct file *file, fl_owner_t id)
    {
    	return 0;
    }
    static const struct file_operations xboxtest_fops = {
    	.owner =	THIS_MODULE,
    	.read =		xbox_read,
    	.write =	xbox_write,
    	.open =		xbox_open,
    	.release =	xbox_release,
    	.flush =	xbox_flush,
    	.llseek =	noop_llseek,
    };
    /*
     * usb class driver info in order to get a minor number from the usb core,
     * and to have the device registered with the driver core
     */
    static struct usb_class_driver xbox_class = {
    	.name =		"xbox%d",
    	.fops =		&xboxtest_fops,
    	.minor_base =	USB_XBOX_MINOR_BASE,
    };
    static struct usb_driver xpad_test_driver;
    static const struct usb_device_id xpad_table[] = {
    	//{ USB_INTERFACE_INFO('X', 'B', 0) },	/* X-Box USB-IF not approved class */
    	//XPAD_XBOX360_VENDOR(0x045e),		/* Microsoft X-Box 360 controllers */
    	{USB_DEVICE(0x045e, 0x028e)},
    	{ }
    };
    static const signed short xpad_common_btn[] = {
    	BTN_A, BTN_B, BTN_X, BTN_Y,			/* "analog" buttons */
    	BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR,	/* start/back/sticks */
    	-1						/* terminating entry */
    };
    MODULE_DEVICE_TABLE(usb, xpad_table);
    static int xpad_init_input(struct usb_xpad *xpad)
    {
    	struct input_dev *input_dev;
    	int i, error;
    	int pipe, maxp;
    	input_dev = input_allocate_device();
    	if (!input_dev)
    		return -ENOMEM;
    	xpad->dev = input_dev;
    	usb_to_input_id(xpad->udev, &input_dev->id);
    	input_set_drvdata(input_dev, xpad);
    	/* set up standard buttons */
    	for (i = 0; xpad_common_btn[i] >= 0; i++)
    		input_set_capability(input_dev, EV_KEY, xpad_common_btn[i]);
    	pipe = usb_rcvintpipe(xpad->udev, xpad->irq_in_endpointAddr);
    	maxp = usb_maxpacket(xpad->udev, pipe, usb_pipeout(pipe));
    	usb_fill_int_urb(xpad->irq_in, xpad->udev,
    			pipe, xpad->data,
    			(maxp > 8 ? 8 : maxp),
    			usb_xpad_irq, xpad, 
    			xpad->endpoint_in->bInterval);
    	error = input_register_device(input_dev);
    	if (error)
    		goto err_free_dev;
    	pr_info("usb input was registered\n");
    	usb_submit_urb(xpad->irq_in, GFP_KERNEL);
    	return 0;	//return ok;
    err_free_dev:
    	input_free_device(input_dev);
    	return error;
    }
    static void xpad_deinit_input(struct usb_xpad *xpad)
    {
    	pr_info("xpad is %p, ->dev is %p.\n",xpad, xpad->dev);
    	if(xpad->dev)
    		input_unregister_device(xpad->dev);
    }
    static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
    {
    	struct usb_xpad *xpad;
    	struct usb_device *udev;
    	struct usb_endpoint_descriptor *ep_irq_in,*ep_irq_out;
    	struct usb_host_interface *intf_tmp;
    	int retval;
    	udev = interface_to_usbdev(intf);
    	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
    	if (!xpad)
    		return -ENOMEM;
    	//초기화
    	//kzallocd으로 0으로 초기화
    	//xpad->odata_serial = 0;
    	xpad->udev = udev;
    	xpad->intf = intf;
    	myPad = xpad;
    	pr_info("xpad is %p, myPad is %p\n", xpad->intf, myPad->intf);
    	pr_info("interface is %p\n", intf);
    	//if (intf->cur_altsetting->desc.bNumEndpoints != 2)
    	//	return -ENODEV;
    	intf_tmp = intf->cur_altsetting;
    	// find common usb endpoint helper 사용
    	//https://lkml.org/lkml/2020/9/21/1239
    	
    	/* set up the endpoint information */
    	/* use only the first bulk-in and bulk-out endpoints */
    	retval = usb_find_common_endpoints(intf_tmp,
    			NULL, NULL, &ep_irq_in, &ep_irq_out);
    	if (retval) {
    		dev_err(&intf->dev,
    			"Could not find both irq-in and irq-out endpoints\n");
    		goto error;
    	}
    	xpad->irq_in_endpointAddr = ep_irq_in->bEndpointAddress;
    	xpad->irq_out_endpointAddr = ep_irq_out->bEndpointAddress;
    	xpad->endpoint_in = ep_irq_in;
    	xpad->endpoint_out = ep_irq_out;
    	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
    	if (!xpad->irq_in) {
    		retval = -ENOMEM;
    		goto err_free_in_urb;
    	}
    	usb_set_intfdata(intf, xpad);
    	pr_info("[info]: found interrupt end point, in: %d, out: %d", ep_irq_in->bEndpointAddress, ep_irq_out->bEndpointAddress);
    	pr_info("probe \n");
    	//pr_info("%04X:%04X pluged \n", id->idVendor, id->idProduct);
    	retval = usb_register_dev(intf, &xbox_class);
    	if (retval< 0) {
    		pr_err("usb_register failed for the "__FILE__ "driver."
    				"Error number %d", retval);
    		usb_set_intfdata(intf, NULL);
    		goto error;
    	}
    	/* let the user know what node this device is now attached to */
    	dev_info(&intf->dev,
    		 "USB Skeleton device now attached to USBSkel-%d",
    		 intf->minor);
    	//input으로 등록.
    	xpad_init_input(xpad);
    	
    	return 0;
    error:
    	kfree(xpad);
    	return retval;
    err_free_in_urb:
    	usb_free_urb(xpad->irq_in);
    	return retval;
    }
    static void xpad_disconnect(struct usb_interface *intf)
    {
    	struct usb_xpad *xpad;
    	xpad = usb_get_intfdata(intf);
    	pr_info("xpad address is %p\n", xpad);
    	xpad_deinit_input(xpad);
    	usb_deregister_dev(intf, &xbox_class);
    	usb_set_intfdata(intf, NULL);
    	kfree(xpad);
    	pr_info("disconnected\n");
    }
    static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
    {
    	pr_info("suspendes\n");
    	return 0;
    }
    static int xpad_resume(struct usb_interface *intf)
    {
    	pr_info("resumed\n");
    	return 0;
    }
    static struct usb_driver xpad_test_driver = {
    	.name		= "xbox360_test",
    	.probe		= xpad_probe,
    	.disconnect	= xpad_disconnect,
    	.suspend	= xpad_suspend,
    	.resume		= xpad_resume,
    	.id_table	= xpad_table,
    };
    static int xpad_init_urb(struct usb_interface *intf, struct usb_xpad *xpad)
    {
    	int retval;
    	xpad->irq_in= usb_alloc_urb(0, GFP_KERNEL);
    	if (!xpad->irq_in) {
    		retval = -ENOMEM;
    		goto error;
    	}
    	return 0;
    error:
    	return retval;
    }
    	
    // 모듈 loading, unloading 테스트를 위해 과거 방식으로 사용
    //module_init(usb_xboxtest_init);
    //module_exit(usb_xboxtest_exit);
    //Macro
    module_usb_driver(xpad_test_driver);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("now0930");
    MODULE_DESCRIPTION("Hello, xbox pad!");
    
    [45180.903315] xpad is ea6ce566, myPad is ea6ce566
    [45180.903332] interface is ea6ce566
    [45180.903349] [info]: found interrupt end point, in: 129, out: 1
    [45180.903360] probe 
    [45180.903636] xbox360_test 1-1.2:1.0: USB Skeleton device now attached to USBSkel-1
    [45180.903815] input: Unspecified device as /devices/virtual/input/input8
    [45180.904290] usb input was registered
    [45180.904475] xpad is 50c63d58, myPad is 50c63d58
    [45180.904489] interface is 50c63d58
    [45180.904506] [info]: found interrupt end point, in: 130, out: 2
    [45180.904518] probe 
    [45180.904685] xbox360_test 1-1.2:1.1: USB Skeleton device now attached to USBSkel-2
    [45180.904841] input: Unspecified device as /devices/virtual/input/input9
    [45180.905155] usb input was registered
    [45180.905310] xpad is 3bfd76ed, myPad is 3bfd76ed
    [45180.905323] interface is 3bfd76ed
    [45180.905342] xbox360_test 1-1.2:1.2: Could not find both irq-in and irq-out endpoints
    [45180.905432] xpad is 07d8d175, myPad is 07d8d175
    [45180.905451] interface is 07d8d175
    [45180.905469] xbox360_test 1-1.2:1.3: Could not find both irq-in and irq-out endpoints
    [45180.905585] usbcore: registered new interface driver xbox360_test
    [45180.909177] test
    [45180.913170] test
    [45210.971462] test
    [45210.984592] test
    [45210.997466] test
    [45211.010595] test
    [45211.075485] test
    [45211.088606] test
    [45211.109483] test
    [45211.130612] test
    [45211.151488] test
    [45211.168617] test
    [45211.181493] test
    [45211.754713] test
    [45211.799598] test
    [45211.812711] test
    [45212.329679] test
    [45217.545918] usbcore: deregistering interface driver xbox360_test
    [45217.546248] test
    [45217.546378] xpad address is 99d70f22
    [45217.546411] xpad is 99d70f22, ->dev is 8784f33d.
    [45217.699130] disconnected
    [45217.699578] test
    [45217.699674] xpad address is 0764c1af
    [45217.699692] xpad is 0764c1af, ->dev is 379dff77.
    [45217.779137] disconnected
  • docker cgoup issue

    docker cgoup issue

    데비안 11로 업데이트 후 에러로 docker를 실행할 수 없다.

    docker: Error response from daemon: cgroups: cgroup mountpoint does not exist: unknown.
    ERRO[0000] error waiting for container: context canceled 

    인터넷에 역시 해결 방법이 있었다.

    I ran into similar issue found a temp fix on another place.
    Temp fix:
    sudo mkdir /sys/fs/cgroup/systemd
    sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd

    /etc/fstab에 기록하면 된다.

    $ cat /etc/fstab | tail -10
    #docker error
    #docker: Error response from daemon: cgroups: cgroup mountpoint does not exist: unknown.
    #mkdir /sys/fs/cgroup/systemd
    #mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
    cgroup	/sys/fs/cgroup/systemd	cgroup	none,name=systemd	0	0

    https://waspro.tistory.com/556

    docker root directory 변경

    https://fliedcat.tistory.com/113

  • 절대쌍교

    절대쌍교

    요즘 넷 플릭스에서 뜨거운 절대쌍교 2020작이다. 1969년 대만 고룡이 쓴 원작으로 2020년 총 44편 드라마로 만들었다. 이렇게까지 길게 만들 필요가 있었나. 간략히 말하면…

    너무 길다.

    이야기가 철학, 끝이 없이 이어진다. 1969년 고룡이 할 말 많았지만, 2020년 드라마 작가가 할 말 많으면 안된다. 대략 10편 내외가 괜찮다고 본다. 중궈 드라마가 인기없는 이유 중 하나다.

    개연성이 떨어진다.

    한 번 등장한 인물이 한 참 뒤 우연하게 자주 등장한다. 주인공과 만나 이야기를 산으로 보낸다. 중국이 정말 크고, 중국인이 정말 많은데 비슷한 장소에서 3개월 전 인물을 또 만날까? 이런 스케일이 강호라면 무림 맹주는 유치원 반장이다.

    이쁜 인물이 많다.

    이 드라마가 가진 가장 강력한 장점이다. 특히 몽꾸냥은 18편 넘어가는 힘든 시기에 보게 하는 원동력이 되었다. 넷플릿스에서 인기있음이 타당하다. 그럼에도 소앵이 나오는 30편부터는 그냥 넘겼다.

    사법 체계가 없다.

    사람이 죽었는데 무림 맹주에게 사건을 해결 해 달라한다. 유방이 유협을 정리하고 1,000년 지나 보이는데 드라마에서 공무원을 찾을 수 없다.

    일본은 20년 전 나온 다이이 대모험을 만들고, 얼마 전 에반게리온 개봉을 했다. 중국은 40년 넘은 원작 소설을 주기적으로 제작하고 있다. 이런 고인물을 만들어도 평타를 치는 중, 일 문제가 있다.

  • 꿈의 에너지, 핵융합

    꿈의 에너지, 핵융합

    isbn: 9788970441832

    원자력 발전을 넘어 에너지 공급 끝판 왕 핵융합을 쉽게 설명한다. 학생 기자와 대학 교수간 대화로 내용을 구성했다. 나름 신선한 시도다. 가뜩이나 어려운 물리학을 질문없이 단방향으로 이해시키기 어렵다. 대화를 주고 받는 형식으로 최대한 독자를 배려했다.

    책 중간에 OHP, KSTAR를 만들것이라고 하여 출판 년도 2018를 잘못 되었다고 의심했다 찾아보니 1쇄 1997년도 출판했다. 2018년도 다시 출판했다.

    책을 보면 핵융합, 핵분열을 이해했다 착각하지 못한다. 다음을 인용했다. 수소가 핵융합을, 우라늄은 핵분열을 시작하여, 철이 그 끝 이다.

    가벼운 원자핵이 합쳐져 더 안정한 무거운 원자핵이 될 때 핵자당 결합에너지가 증가하는데, 결합에너지는 질량의 일부로 사용되어 핵자당 질량이 감소하게 된다. 똑같이 무거운 원자핵이 핵분열하여 더 안정한 가벼운 원자핵이 될 때, 핵자당 질량이 감소한다. 이렇게 핵반응에서 질량결손이 생겨 에너지가 방출되는 것이다. 가벼운 원자핵이 핵융합할 때 에너지를 방출하고 핵분열하려면 에너지를 흡수해야 하며, 무거운 원자핵이 핵융합하려면 에너지를 흡수해야 하고 핵분열하면 에너지를 방출하는 이유이기도 하다.
    핵자당 결합에너지가 가장 높아 가장 안정적인 원자핵인 Fe-56은 핵자당 질량이 가장 작다. 때문에 Fe-56이 핵융합하거나 핵분열하려면 에너지를 흡수해야 하고 핵융합하면 에너지를 방출하며, Fe-56으로 핵융합하거나 핵분열하면 에너지를 방출하는데, 상대적으로 주변 원소들에 비해 존재비가 높은 이유이기도 하다.

    namu.wiki/w/핵융합

    저자 걱정과 다르게 한국이 핵융합 연구를 활발히 하고 있다. 지구 미래, 환경을 걱정하는 공학도, 과학자라면 대규모 프로젝트 핵융합에 인생을 걸 만하다. 기술 발달로 과거 보이지 않는 여러 현상을 밝혀낼 수 있게 되었다. 국내 여러 능력자들이 이 분야에 활동했으면 한다. 인간이 지구를 너무 착취하니 인간 욕망을 통제해야 한다 주장하는 급격한 환경운동가보다 1,000배는 진취적이다.