# Linux Kernel Quick Question ###### tags: `Interview` `linuxKernel` `EMBEDDED_C 1. hello world moudle 怎寫 ```clike= #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_fdt.h> #include <linux/of_platform.h> MODULE_LICENSE("Dual BSD/GPL"); static int __init device_tree_init(void) { /* a pointer point to a device_node struct */ printk(" ---------------------------------\n"); struct device_node *np; printk("device tree start checking the node\n"); /* Disable SMP boot unless both CPUs are listed in DT and !disabled */ np = of_find_node_by_name(NULL, "uart1"); pr_info("start checking the node with np of ptr\n"); if (np =! NULL){ pr_info("%s find node in dts\n",__func__); } else{ pr_err("%s error: cannot find the the node in dts\n",__func__); } return 0; } static void __exit device_tree_exit(void) { printk("end of the module\n"); printk("--------------------------------------------------------------------------\n"); } /* * load a Linux driver */ module_init(device_tree_init); /* * unload the Linux driver */ module_exit(device_tree_exit); ``` ### 2. Entry Point / Exit Point of the Kernel Module ```clike= module_init(*_init_module); module_exit(*_exit_module); ``` * #### What does it mean `__init`? * #### What does it mean `__exit`? ### 4. character device driverv .read .write 怎寫 * `struct file_opertion` ```clike= const struct file_operations my_fops = { .owner = THIS_MODULE, .open = my_open, .read = my_read, .write = my_write, .release = my_release, .unlocked_ioctl = my_ioctl }; ``` * Read ```clike= static int my_read(struct file *file, char __user *user_buffer, size_t size, loff_t *offset) { struct my_device_data *my_data = (struct my_device_data *) file->private_data; ssize_t len = min(my_data->size - *offset, size); if (len <= 0) return 0; /* read data from my_data->buffer to user buffer */ if (copy_to_user(user_buffer, my_data->buffer + *offset, len)) return -EFAULT; *offset += len; return len; } ``` * Write ```clike= static int my_read(struct file *file, char __user *user_buffer, size_t size, loff_t *offset) { struct my_device_data *my_data = (struct my_device_data *) file->private_data; ssize_t len = min(my_data->size - *offset, size); if (len <= 0) return 0; /* read data from my_data->buffer to user buffer */ if (copy_to_user(user_buffer, my_data->buffer + *offset, len)) return -EFAULT; *offset += len; return len; } ``` ### 6. kconfig怎加 * `Make Menuconfig`加入後 ### 7. config 放哪,如何更改 * `make menuconfig` 生成新的config file ### 8. build完Kernel後會產生幾種類型的檔以及格式的差異-[Refefrence](https://www.cnblogs.com/lemaden/p/10438499.html) * **`vmlinux`**: * directory:`/arh/arm/boot/compressed` * vm代表Virtual Memory, * File Format(using `file` command to check) * #### ELF * statically linked,ELF 32-bit LSB executable * **`dtb`**: * directory:`/arch/arm/boot/dts` * File Format * imx6ul-panzer.dtb: Device Tree Blob version 17, size=36467, boot CPU=0, string block size=2587, **DT structure** block size=33824 * **`zImage`**: * directory: `arch/arm/boot/compressed/vmlinux` * **壓縮過後的vmlinux**, 它是由vmlinux經過objcopy,objcopy實現由vmlinux的elf文件複製成純binary file並由gzip壓縮分解而成 * File Format: * Linux kernel ARM boot executable zImage (little-endian) ### 9. build完產物放哪 * dtb-> `/arch/arm/boot/dts` * zImage-> --- ### 10. dts怎改 --- ### 11. image格式差異 ?? ### ### 12. external ko怎build * Refernece 編譯過得source code * `Makefile`, `.c` * `export ARCH = ` * `export Cross_Compile` * `Make` * Insert Module * `modprobe` * `insertmode` --- ### 13. Makefile怎寫 ```script= obj-m :=smnt_falt.o KDIR :=/home/paul/Panzer/linux-imx_4_9MYCC =/home/paul/opt/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- # The KDIR must have to assign a ./direction modules: $(MAKE) ARCH=arm CROSS_COMPILE=$(MYCC) -C $(KDIR) SUBDIRS=$(shell pwd) modules clean: rm -f modules.order Module.symvers *.o *.ko *.mod.c ``` ### 語法整理 #### **`:=`** `:=`注意到,make 會將整個 Makefile 展開後,再決定變數的值。也就是說,變數的值將會是整個 Mackfile 中最後被指定的值。 #### **`?=`** `?=`是一個簡化的語法:若變數未定義,則替它指定新的值。 否則,採用原有的值。 * e.g:`Foo?=` #### **`+=`** 若變數未定義,則替它指定新的值。否則,採用原有的值。 * e.g:`` --- ### 14. compiler怎指定??? `export ARCH=arm` `export CROSS_COMPILE=/gcc-arm */bin/arm-none-eabi-` ### 15. kernel版本怎看 * 透過板子 * `uname -a` * `cat /proc/version` * 參考Makfile * Makefile一開始就會寫出 ```clike= # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 14 SUBLEVEL = 78 EXTRAVERSION = NAME = Petit Gorille ``` ### 16. 反組譯看dump??? ### 17. 板子上常用指令 #### **`cat proc interrupt`** * e.g: ``` CPU0 CPU1 CPU2 CPU3 0: 3710374484 0 0 0 IO-APIC-edge timer 1: 20 0 0 0 IO-APIC-edge i8042 6: 5 0 0 0 IO-APIC-edge floppy 7: 0 0 0 0 IO-APIC-edge parport0 8: 0 0 0 0 IO-APIC-edge rtc 9: 0 0 0 0 IO-APIC-level acpi 12: 240 0 0 0 IO-APIC-edge i8042 14: 11200026 0 0 0 IO-APIC-edge ide0 51: 61281329 0 0 0 IO-APIC-level ioc0 59: 1 0 0 0 IO-APIC-level vmci 67: 19386473 0 0 0 IO-APIC-level eth0 75: 94595340 0 0 0 IO-APIC-level eth1 NMI: 0 0 0 0 LOC: 3737150067 3737142382 3737145101 3737144204 ERR: 0 MIS: 0 ``` * IRQ > IRQ0 — system timer (cannot be changed); > IRQ1 — keyboard controller (cannot be changed) > IRQ3 — serial port controller for serial port 2 (shared with serial port 4, if present); > IRQ 4 — serial port controller for serial port 1 (shared with serial port 3, if present); > IRQ 5 — parallel port 2 and 3 or sound card; > IRQ 6 — floppy disk controller; > IRQ 7 — parallel port 1. It is used for printers or for any parallel port if a printer is not present. #### **`cat proc vmalloc`** #### **`cat proc meminfo`** > The ‘/proc/meminfo‘ is used by to report the amount of free and used memory (both physical and swap) on the system as well as the shared memory and buffers used by the kernel. ``` MemTotal: 1882064 kB MemFree: 1376380 kB MemAvailable: 1535676 kB Buffers: 2088 kB Cached: 292324 kB SwapCached: 0 kB Active: 152944 kB Inactive: 252628 kB Active(anon): 111328 kB Inactive(anon): 16508 kB Active(file): 41616 kB Inactive(file): 236120 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 2097148 kB SwapFree: 2097148 kB Dirty: 40 kB Writeback: 0 kB AnonPages: 111180 kB Mapped: 56396 kB Shmem: 16676 kB Slab: 54508 kB SReclaimable: 25456 kB SUnreclaim: 29052 kB KernelStack: 2608 kB PageTables: 5056 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3038180 kB Committed_AS: 577664 kB VmallocTotal: 34359738367 kB VmallocUsed: 14664 kB VmallocChunk: 34359717628 kB HardwareCorrupted: 0 kB AnonHugePages: 24576 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 69632 kB DirectMap2M: 2027520 kB ``` * #### Module * Add Module * `insmod` * `modprobe` * Display the current moad module * `lsmod` * Remove the module * `rmmod` * Get Information of the module * `modinfo` * log level Set Up 19. What's`device tree` * #### Hardware description file >Device Tree is a document to tell us about the Hardware's architecture, for example we would know how many of hardware chips in this hardware. * #### properties and nodes >where devices are represented by nodes with their properties. * #### What's the purpose of it and which Kernel Version start to have ? ### 18. driver 怎麼拿到device tree裡面東西? > 透過of_node_系列的API * `of_find_node_by_name` ```clike= //of_find_node_by_name struct device_node *np1 = NULL; printk("decalre a pointer np1 point to the struct of device_node\n"); np1 = of_find_node_by_name(NULL, "uart1"); ``` * `of_machine_is_compatible` ```clike= if (of_machine_is_compatible("fsl,imx8qm")) imx8qm_get_mac_from_fuse(idx, mac, &imx8_fuse_mapping[IMX8QM_FUSE]); else if (of_machine_is_compatible("fsl,imx8qxp")) imx8qm_get_mac_from_fuse(idx, mac, &imx8_fuse_mapping[IMX8QXP_FUSE]); ``` ### 19. What's the three types of Device Driver: * Character Device Module * Block Device Module * Network Interface Module ### 20. Linux Kernel可以被簡單分為以下幾個區塊: * Process management >Kernel負責創造銷毀Process,並且也handling their connection to the outside world (input and output)。與不同的Process溝通(signals、pipe、 interprocess communication primitives)是整個系統的基礎,也是由Kernel掌控。CPU的process排成也是歸類在這,Kernel可以在單CPU或多CPU上跑虛擬的多個process。 * Memory management > 記憶體是重要資源,並且如何用它也成為效能關鍵。Kernel建了虛擬記憶體空間,並且所有processes都是在上面被控管資源的方式執行。所有kernel使用Memory management都是透過 malloc/free這組函數來與之互動的,複雜一點的函數裡面也是malloc/free。 * Filesystems >Unix就是基於Filesystems的一個作業系統,幾乎所有東西在Unix裡面都能被當作一個檔案。Kernel會建 structured filesystem on top of unstructured hardware,這個抽象的檔案才會被系統用力的使用。Linux支援多種不同 filesystem類別,可以有不同方法來 organizing data on the physical medium。例如磁碟可以格式化成Linux-standard ext3 filesystem,或是 FAT filesystem等等的。 * Device control > 幾乎所有 system operation都會最終map到硬體。除了 processor、 memory還有一些其他以外,所有device control operations都由一段 specific to the device being addressed的code來執行,這個code就是device driver。所有 peripheral想在掛在系統都要由kernel給他device driver,包括硬碟、鍵盤、磁碟。這部分就是本書重點。 * Networking > Networking一定要透過 operating system管理,因為多數network都不是為了單一特定process。在process拿到 packets前, packets都會經過 collected, identified, and dispatched的程序。系統負責透過程式跟 network interfaces來傳packet,然後依據 network activity來控制程式的執行。此外,所有routing and address resolution issues都在kernel中實現。 ### 21. Probe()怎麼去實做的 ### 23. What's the Linux syscall? ans * socket * write * malloc ### 24. What script would you use to check that a file compiles with Linux Kernel Coding Style ### 25. What's the command to get kernel log? * `demsg` * `cat /log/....` ### 26. What is the file used to describe the hardware architecture of ARM platform when compileing the linux kernel? > dts ### 27. What is the file used to describe the hardware architecture of ARM platform when compileing the linux kernel? > dtb ### 28. What commmand is used to view systemed logs? * What's `systemed` logs? * systemctl * Any text file will work * syslogctl * rsyslog * journalctl ### 29.Consider the ollowing mount output Which file system is read only? ![](https://i.imgur.com/OgiLgrs.png) * securityfs * devpts * tmpfs * systemd-1 * /dev/xvdb ### 30.Which command could you use to back up a disk device without mounting at first? ### 31.What's the name of the document where you would find technical characteristics of a product,machine,component? ### 32.What's the name of the default distribution of yocto? ### 33.What's the name of the configuration file where the machine is genarlly defined? ### 34.What's the correct way to modify an exiting recipe? ### 35. [What's the booting process?](https://hackmd.io/pVjnSuIkTVaibWFUK4RfEw?both)-in Panzer --- ### 36. embedeed linux中tty的架構? --- ### 37. Big Endian && Little Endian * Adress from low to high * E.G: `0xFF00AB11` * **Big Endian**越前面放的越重要 | Address | 0x4000 | 0x4001 |0x4002 |0x4003 | -------- | -------- | -------- | --------| --------| | **Byte Order** | byte0 | byte 1|byte 2|byte 3 | **Value** | 0xFF | 0x00|0xAB|0x11| * **Little Endian** ->相反 | Address | 0x4000 | 0x4001 |0x4002 |0x4003 | | -------- | -------- | -------- | --------| --------| | **Byte Order** | byte0 | byte 1|byte 2|byte 3 | **Value** | 0x11 | 0xAB|0x00|0xFF| * #### Chck it with C programming ```clike= #include <stdio.h> #include <stdlib.h> #include <stdint.h> union Endian{ char c[64]; uint64_t i; }; // 1 Byte = 8 bit can be expressed 0xFF. int main(void){ union Endian Var; Var.i = (uint64_t)0x11223344;//0x11223344; //(4 + 4 + 4 +4) = 64 bit; printf("sizeof is %ld\n",sizeof(Var.c[0])); printf("The adrees of %p and val is %x \n",&(Var.c[0]),Var.c[0]); printf("The adrees of %p and val is %x \n",&(Var.c[1]),Var.c[1]); printf("The adrees of %p and val is %x \n",&(Var.c[2]),Var.c[2]); printf("The adrees of %p and val is %x \n",&(Var.c[3]),Var.c[3]); if(Var.c[0] == 0x11) printf("Big Endian\n"); else printf("Little Endian\n"); return 0; } ``` ### 38. Where's the kernel entry point * `start_kernel`