{"id":338674,"date":"2022-09-23T15:00:11","date_gmt":"2022-09-23T15:00:11","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=338674"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=338674","title":{"rendered":"<span>\u041f\u043e\u0441\u043e\u0431\u0438\u0435 \u043f\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u044f\u0434\u0440\u0430 Linux. \u0427.7<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/688564\/\"><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/-7\/yl\/hp\/-7ylhpzc6raohz-vopxottyejfu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/-7\/yl\/hp\/-7ylhpzc6raohz-vopxottyejfu.png\"\/><\/div>\n<p><\/a><br \/>  \u0417\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u044f\u0434\u0440\u0430 \u043e\u0442 02 \u0438\u044e\u043b\u044f 2022 \u0433\u043e\u0434\u0430. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439, \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044e, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0434\u0435\u043b\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438. \u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0436\u0435 \u044f \u0443\u043a\u0430\u0436\u0443 \u043d\u0430 \u043f\u0430\u0440\u0443 \u043d\u0435\u044f\u0432\u043d\u044b\u0445, \u043d\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u043d\u044e\u0430\u043d\u0441\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u043f\u043e \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c\u0443 \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u044e \u0432 \u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f\u0434\u0440\u0430.<a name=\"habracut\"><\/a><\/p>\n<h2><font color=\"#3AC1EF\">\u258d \u0413\u043e\u0442\u043e\u0432\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430:<\/font><\/h2>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/681880\/\">\u0427\u0430\u0441\u0442\u044c 1<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/683106\/\">\u0427\u0430\u0441\u0442\u044c 2<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/684382\/\">\u0427\u0430\u0441\u0442\u044c 3<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/685168\/\">\u0427\u0430\u0441\u0442\u044c 4<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/686596\/\">\u0427\u0430\u0441\u0442\u044c 5<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/688564\/\">\u0427\u0430\u0441\u0442\u044c 6<\/a><\/li>\n<li> <b><font color=\"#3AC1EF\">\u0412\u044b \u0442\u0443\u0442 &#8212;> <\/font><\/b><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/689346\/\">\u0427\u0430\u0441\u0442\u044c 7<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<h2><font color=\"#3AC1EF\">15. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439<\/font><\/h2>\n<p>  <\/p>\n<h3><font color=\"#3AC1EF\">\u258d 15.1 \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439<\/font><\/h3>\n<p>  \u0412\u043e \u0432\u0441\u0435\u0445 \u0433\u043b\u0430\u0432\u0430\u0445 (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439), \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u0432 \u044f\u0434\u0440\u0435 \u043b\u0438\u0448\u044c \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432, \u0434\u043b\u044f \u0447\u0435\u0433\u043e-\u043b\u0438\u0431\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u043e\u0441\u043e\u0431\u044b\u043c \u0444\u0430\u0439\u043b\u043e\u043c, \u043b\u0438\u0431\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0438 <code>ioctl()<\/code> \u0438\u043b\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432. \u041d\u043e \u0440\u0430\u0431\u043e\u0442\u0430 \u044f\u0434\u0440\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432. \u0415\u0449\u0451 \u043e\u0434\u043d\u043e\u0439 \u0435\u0433\u043e \u043d\u0435\u043c\u0430\u043b\u043e\u0432\u0430\u0436\u043d\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u043c \u043a \u043c\u0430\u0448\u0438\u043d\u0435 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c.<\/p>\n<p>  \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0430 \u0442\u0438\u043f\u0430 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u0426\u041f\u0423 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u2013 \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0426\u041f\u0423 \u043e\u0442\u0434\u0430\u0451\u0442 \u0435\u043c\u0443 \u0440\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0435\u043d\u0438\u044f. \u0420\u0430\u0441\u043f\u043e\u0440\u044f\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u0447\u0442\u043e-\u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0443. \u0412\u0442\u043e\u0440\u043e\u0439, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438, \u0443\u0436\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u044e, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0443. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u043e\u0441\u043d\u0430\u0449\u0435\u043d\u044b \u043e\u0447\u0435\u043d\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u0431\u044a\u0451\u043c\u043e\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u0438 \u0435\u0441\u043b\u0438 \u0441\u0432\u043e\u0435\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u0443\u044e \u0438\u043c\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u0430.<\/p>\n<p>  \u0412 Linux \u2014 \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f IRQ (Interrupt ReQuests). \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0430 \u0442\u0438\u043f\u0430 IRQ, \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u0438 \u0434\u043b\u0438\u043d\u043d\u044b\u0435. \u041a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f, \u043a\u0430\u043a \u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0445 \u0438\u043c\u044f, \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u0440\u0430\u0442\u043a\u0438\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u044b \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u0414\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0436\u0435 IRQ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438 \u043d\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c IRQ \u043e\u0442 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430). \u041f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438.<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u0426\u041f\u0423 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435, \u043e\u043d \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u0441\u0432\u043e\u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u043e\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435; \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043d \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e), \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432 \u0441\u0442\u0435\u043a\u0435 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044f\u0434\u0440\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438. \u041f\u0435\u0440\u0432\u0430\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0438 \u043c\u0430\u0441\u043a\u0438\u0440\u0443\u0435\u0442 \u043b\u0438\u043d\u0438\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439. \u0410\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u043e, \u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0430\u044f \u0432\u0441\u044e \u0442\u044f\u0436\u0451\u043b\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443, \u043e\u0442\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u043e\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041f\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c BH (\u0430\u0431\u0431\u0440\u0435\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u0434\u043b\u044f \u041d\u0438\u0436\u043d\u0438\u0445 \u043f\u043e\u043b\u043e\u0432\u0438\u043d) \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0435\u0434\u0451\u0442 \u0443\u0447\u0451\u0442 \u044d\u0442\u0438\u0445 \u043e\u0442\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 Linux 2.3, \u043d\u0430 \u0441\u043c\u0435\u043d\u0443 BH \u043f\u0440\u0438\u0448\u0451\u043b \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c Softirq \u0438 \u0435\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f Tasklet.<\/p>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u044d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 <code>request_irq()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a.<\/p>\n<p>  \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 IRQ \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0417\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0438\u0437 \u0434\u0432\u0443\u0445 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0451 IRQ, \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0435 \u043e\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0412, \u043a\u0430\u0441\u043a\u0430\u0434\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0435 IRQ \u043e\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0410. \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f\u0434\u0440\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a\u043e\u0435 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443. \u0412 \u0434\u0440\u0443\u0433\u0438\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\u0445 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043e\u0441\u043e\u0431\u044b\u0439 \u0432\u0438\u0434 \u043c\u0435\u043d\u0435\u0435 \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u00abfast IRQ\u00bb, \u0438\u043b\u0438 FIQ. \u0414\u043b\u044f \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435, \u0432 \u0441\u0432\u044f\u0437\u0438 \u0441 \u0447\u0435\u043c \u044f\u0434\u0440\u0443 \u043e\u043d\u0438 \u0443\u0436\u0435 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442. \u041c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0434\u0440\u0443\u0433\u0438\u043c, \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0443\u0442\u0440\u0430\u0442\u044f\u0442 \u0441\u0432\u043e\u0451 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0432 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438. \u042f\u0434\u0440\u0430 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 SMP, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430\u043c\u0438, \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0435\u0448\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435, \u0442\u0430\u043a\u0436\u0435 \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0434\u043b\u044f \u043a\u0430\u043a\u043e\u0433\u043e (\u0438\u043b\u0438 \u043a\u0430\u043a\u0438\u0445) \u0426\u041f\u0423 \u043e\u043d\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043e. \u0422\u0435\u043c, \u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u043e <a href=\"https:\/\/ru.wikipedia.org\/wiki\/APIC\">\u201cAPIC\u201d (Advanced Programmable Interrupt Controller \u2014 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439)<\/a>.<\/p>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>request_irq<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043d\u043e\u043c\u0435\u0440 IRQ, \u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0444\u043b\u0430\u0433\u0438, \u0438\u043c\u044f \u0434\u043b\u044f <code>\/proc\/interrupts<\/code> \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e IRQ, \u043a\u0430\u043a\u043e\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u2013 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u043b\u0430\u0433\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <code>SA_SHIRQ<\/code>, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u044d\u0442\u0438\u043c IRQ \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 (\u043e\u0431\u044b\u0447\u043d\u043e \u0432\u0432\u0438\u0434\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0440\u044f\u0434 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u0441\u0438\u0434\u044f\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c IRQ) \u0438 <code>SA_INTERRUPT<\/code>, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0438\u0439 \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0435\u0449\u0451 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0438\u043b\u0438 \u0435\u0441\u043b\u0438 \u0432\u044b \u0442\u0430\u043a\u0436\u0435 \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u043c \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f.<\/p>\n<h3><font color=\"#3AC1EF\">\u258d 15.2 \u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u0439 \u043a\u043b\u0430\u0432\u0438\u0448<\/font><\/h3>\n<p>  \u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a Raspberry Pi \u0438\u043b\u0438 Beegleboards, \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u044b \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u043e\u0432 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u044d\u0442\u0438\u043c \u0432\u044b\u0432\u043e\u0434\u0430\u043c \u043a\u043d\u043e\u043f\u043e\u043a \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0438\u0445 \u043d\u0430\u0436\u0430\u0442\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0438 \u044d\u043d\u0435\u0440\u0433\u0438\u044e \u043d\u0430 \u043e\u043f\u0440\u043e\u0441 \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043b\u0443\u0447\u0448\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0445\u043e\u0434 \u043d\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044e \u0426\u041f\u0423 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>  \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a \u0432\u044b\u0432\u043e\u0434\u0430\u043c 17 \u0438 18, \u0430 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u043a \u0432\u044b\u0432\u043e\u0434\u0443 4. \u041f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u043e\u043c\u0435\u0440\u0430 \u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u043d\u0430 \u0441\u0432\u043e\u0451 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">intrpt.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * intrpt.c \u2013 \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439.  *  * \u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0432\u0437\u044f\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 RPi \u0421\u0442\u0435\u0444\u0430\u043d\u0430 \u0412\u0435\u043d\u0434\u043b\u0435\u0440\u0430 (devnull@kaltpost.de)  * \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f https:\/\/github.com\/wendlers\/rpi-kmod-samples  *  * \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043e\u0434\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u0437\u0430\u0433\u043e\u0440\u0430\u0435\u0442\u0441\u044f, \u0430 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u0434\u0440\u0443\u0433\u043e\u0439  * \u0433\u0430\u0441\u043d\u0435\u0442.  *\/   #include &lt;linux\/gpio.h> #include &lt;linux\/interrupt.h> #include &lt;linux\/kernel.h> #include &lt;linux\/module.h>   static int button_irqs[] = { -1, -1 };   \/* \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u0432.  * \u041d\u043e\u043c\u0435\u0440\u0430 \u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c.  *\/ static struct gpio leds[] = { { 4, GPIOF_OUT_INIT_LOW, \"LED 1\" } };   \/* \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0434\u043b\u044f BUTTONS.  * \u041d\u043e\u043c\u0435\u0440\u0430 \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c.  *\/ static struct gpio buttons[] = { { 17, GPIOF_IN, \"LED 1 ON BUTTON\" },                                  { 18, GPIOF_IN, \"LED 1 OFF BUTTON\" } };   \/* \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439, \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0438. *\/ static irqreturn_t button_isr(int irq, void *data) {     \/* \u041f\u0435\u0440\u0432\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430. *\/     if (irq == button_irqs[0] &amp;&amp; !gpio_get_value(leds[0].gpio))         gpio_set_value(leds[0].gpio, 1);     \/* \u0412\u0442\u043e\u0440\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430. *\/     else if (irq == button_irqs[1] &amp;&amp; gpio_get_value(leds[0].gpio))         gpio_set_value(leds[0].gpio, 0);       return IRQ_HANDLED; }   static int __init intrpt_init(void) {     int ret = 0;       pr_info(\"%s\\n\", __func__);       \/* \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u0432. *\/     ret = gpio_request_array(leds, ARRAY_SIZE(leds));       if (ret) {         pr_err(\"Unable to request GPIOs for LEDs: %d\\n\", ret);         return ret;     }       \/* \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0434\u043b\u044f BUTTON. *\/     ret = gpio_request_array(buttons, ARRAY_SIZE(buttons));       if (ret) {         pr_err(\"Unable to request GPIOs for BUTTONs: %d\\n\", ret);         goto fail1;     }       pr_info(\"Current button1 value: %d\\n\", gpio_get_value(buttons[0].gpio));       ret = gpio_to_irq(buttons[0].gpio);       if (ret &lt; 0) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail2;     }       button_irqs[0] = ret;       pr_info(\"Successfully requested BUTTON1 IRQ # %d\\n\", button_irqs[0]);       ret = request_irq(button_irqs[0], button_isr,                       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,                       \"gpiomod#button1\", NULL);       if (ret) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail2;     }       ret = gpio_to_irq(buttons[1].gpio);       if (ret &lt; 0) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail2;     }       button_irqs[1] = ret;       pr_info(\"Successfully requested BUTTON2 IRQ # %d\\n\", button_irqs[1]);       ret = request_irq(button_irqs[1], button_isr,                       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,                       \"gpiomod#button2\", NULL);       if (ret) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail3;     }       return 0;   \/* \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. *\/ fail3:     free_irq(button_irqs[0], NULL);   fail2:     gpio_free_array(buttons, ARRAY_SIZE(leds));   fail1:     gpio_free_array(leds, ARRAY_SIZE(leds));       return ret; }   static void __exit intrpt_exit(void) {     int i;       pr_info(\"%s\\n\", __func__);       \/* \u0421\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f. *\/     free_irq(button_irqs[0], NULL);     free_irq(button_irqs[1], NULL);       \/* \u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u0432. *\/     for (i = 0; i &lt; ARRAY_SIZE(leds); i++)         gpio_set_value(leds[i].gpio, 0);       \/* \u0421\u043d\u044f\u0442\u0438\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438. *\/     gpio_free_array(leds, ARRAY_SIZE(leds));     gpio_free_array(buttons, ARRAY_SIZE(buttons)); }   module_init(intrpt_init); module_exit(intrpt_exit);   MODULE_LICENSE(\"GPL\"); MODULE_DESCRIPTION(\"Handle some GPIO interrupts\");<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h3><font color=\"#3AC1EF\">\u258d 15.3 \u041d\u0438\u0436\u043d\u044f\u044f \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430<\/font><\/h3>\n<p>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u044f\u0434 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043e\u0434\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e, \u043d\u0435 \u043b\u0438\u0448\u0430\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0434\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0435\u0433\u043e \u0441\u043e\u0432\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0441 \u0442\u0430\u0441\u043a\u043b\u0435\u0442\u043e\u043c. \u0422\u0430\u043a \u0432\u044b \u043f\u0435\u0440\u0435\u043b\u043e\u0436\u0438\u0442\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a.<\/p>\n<p>  \u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">bottomhalf.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * bottomhalf.c \u2013 \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0438 \u043d\u0438\u0436\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0435\u0439 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.  *  * \u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0432\u0437\u044f\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 RPi \u0421\u0442\u0435\u0444\u0430\u043d\u0430 \u0412\u0435\u043d\u0434\u043b\u0435\u0440\u0430 (devnull@kaltpost.de)  * \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f https:\/\/github.com\/wendlers\/rpi-kmod-samples  *  * \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043e\u0434\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434 \u0437\u0430\u0433\u043e\u0440\u0430\u0435\u0442\u0441\u044f, \u0430 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u0434\u0440\u0443\u0433\u043e\u0439  * \u0433\u0430\u0441\u043d\u0435\u0442.  *\/   #include &lt;linux\/delay.h> #include &lt;linux\/gpio.h> #include &lt;linux\/interrupt.h> #include &lt;linux\/kernel.h> #include &lt;linux\/module.h>   \/* \u041c\u0430\u043a\u0440\u043e\u0441 DECLARE_TASKLET_OLD \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u043b\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438.  * \u0421\u043c. https:\/\/lwn.net\/Articles\/830964\/  *\/ #ifndef DECLARE_TASKLET_OLD #define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L) #endif   static int button_irqs[] = { -1, -1 };   \/* \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u0432.  * \u041d\u043e\u043c\u0435\u0440\u0430 \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c.  *\/ static struct gpio leds[] = { { 4, GPIOF_OUT_INIT_LOW, \"LED 1\" } };   \/* \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0434\u043b\u044f BUTTONS.  * \u041d\u043e\u043c\u0435\u0440\u0430 \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c.  *\/ static struct gpio buttons[] = {     { 17, GPIOF_IN, \"LED 1 ON BUTTON\" },     { 18, GPIOF_IN, \"LED 1 OFF BUTTON\" }, };   \/* \u0422\u0430\u0441\u043a\u043b\u0435\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0451\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. *\/ static void bottomhalf_tasklet_fn(unsigned long data) {     pr_info(\"Bottom half tasklet starts\\n\");     \/* \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439. *\/     mdelay(500);     pr_info(\"Bottom half tasklet ends\\n\"); }   static DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn);       \/* \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f, \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438. *\/ static irqreturn_t button_isr(int irq, void *data) {     \/* \u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0440\u044f\u043c\u043e \u0441\u0435\u0439\u0447\u0430\u0441. *\/     if (irq == button_irqs[0] &amp;&amp; !gpio_get_value(leds[0].gpio))         gpio_set_value(leds[0].gpio, 1);     else if (irq == button_irqs[1] &amp;&amp; gpio_get_value(leds[0].gpio))         gpio_set_value(leds[0].gpio, 0);       \/* \u041d\u0435\u0441\u043f\u0435\u0448\u043d\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a. *\/     tasklet_schedule(&amp;buttontask);       return IRQ_HANDLED; }   static int __init bottomhalf_init(void) {     int ret = 0;       pr_info(\"%s\\n\", __func__);       \/* \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u0432. *\/     ret = gpio_request_array(leds, ARRAY_SIZE(leds));       if (ret) {         pr_err(\"Unable to request GPIOs for LEDs: %d\\n\", ret);         return ret;     }       \/* \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u0432\u043e\u0434\u043e\u0432-\u0432\u044b\u0432\u043e\u0434\u043e\u0432 BUTTONS. *\/     ret = gpio_request_array(buttons, ARRAY_SIZE(buttons));       if (ret) {         pr_err(\"Unable to request GPIOs for BUTTONs: %d\\n\", ret);         goto fail1;     }       pr_info(\"Current button1 value: %d\\n\", gpio_get_value(buttons[0].gpio));       ret = gpio_to_irq(buttons[0].gpio);       if (ret &lt; 0) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail2;     }       button_irqs[0] = ret;       pr_info(\"Successfully requested BUTTON1 IRQ # %d\\n\", button_irqs[0]);       ret = request_irq(button_irqs[0], button_isr,                       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,                       \"gpiomod#button1\", NULL);       if (ret) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail2;     }       ret = gpio_to_irq(buttons[1].gpio);       if (ret &lt; 0) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail2;     }       button_irqs[1] = ret;       pr_info(\"Successfully requested BUTTON2 IRQ # %d\\n\", button_irqs[1]);       ret = request_irq(button_irqs[1], button_isr,                       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,                       \"gpiomod#button2\", NULL);       if (ret) {         pr_err(\"Unable to request IRQ: %d\\n\", ret);         goto fail3;     }       return 0;   \/* \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. *\/ fail3:     free_irq(button_irqs[0], NULL);   fail2:     gpio_free_array(buttons, ARRAY_SIZE(leds));   fail1:     gpio_free_array(leds, ARRAY_SIZE(leds));       return ret; }   static void __exit bottomhalf_exit(void) {     int i;       pr_info(\"%s\\n\", __func__);       \/* \u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439. *\/     free_irq(button_irqs[0], NULL);     free_irq(button_irqs[1], NULL);       \/* \u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u0432. *\/     for (i = 0; i &lt; ARRAY_SIZE(leds); i++)         gpio_set_value(leds[i].gpio, 0);       \/* \u041e\u0442\u043c\u0435\u043d\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438. *\/     gpio_free_array(leds, ARRAY_SIZE(leds));     gpio_free_array(buttons, ARRAY_SIZE(buttons)); }   module_init(bottomhalf_init); module_exit(bottomhalf_exit);   MODULE_LICENSE(\"GPL\"); MODULE_DESCRIPTION(\"Interrupt with top and bottom half\");<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h2><font color=\"#3AC1EF\">16. \u041a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f<\/font><\/h2>\n<p>  \u041d\u0430 \u0437\u0430\u0440\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430 \u0432\u0441\u0435 \u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0434\u043e\u0432\u0435\u0440\u044f\u043b\u0438 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443\u2026\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0432\u044b\u0448\u043b\u043e. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u0438\u0441\u0430\u043b\u043e\u0441\u044c \u0432 \u0431\u0435\u0437\u043c\u044f\u0442\u0435\u0436\u043d\u0443\u044e \u044d\u0440\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u0430\u043b\u043e \u043a\u043e\u0433\u043e \u0437\u0430\u0431\u043e\u0442\u0438\u043b\u0430 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044f \u2013 \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u044f\u0434\u0440\u0430. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0436\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u0438\u0435. \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0432 \u044f\u0434\u0440\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 API, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f\/\u0434\u0435\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0438 \u0432\u0430\u0448\u0438 \u043b\u044e\u0431\u0438\u043c\u044b\u0435 \u0445\u0435\u0448-\u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<h3><font color=\"#3AC1EF\">\u258d 16.1 \u0425\u0435\u0448-\u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/font><\/h3>\n<p>  \u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0445\u0435\u0448\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439. \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0445\u0435\u0448\u0430 sha256 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 \u044f\u0434\u0440\u0430.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">cryptosha256.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * cryptosha256.c  *\/ #include &lt;crypto\/internal\/hash.h> #include &lt;linux\/module.h>   #define SHA256_LENGTH 32   static void show_hash_result(char *plaintext, char *hash_sha256) {     int i;     char str[SHA256_LENGTH * 2 + 1];       pr_info(\"sha256 test for string: \\\"%s\\\"\\n\", plaintext);     for (i = 0; i &lt; SHA256_LENGTH; i++)         sprintf(&amp;str[i * 2], \"%02x\", (unsigned char)hash_sha256[i]);     str[i * 2] = 0;     pr_info(\"%s\\n\", str); }   static int cryptosha256_init(void) {     char *plaintext = \"This is a test\";     char hash_sha256[SHA256_LENGTH];     struct crypto_shash *sha256;     struct shash_desc *shash;       sha256 = crypto_alloc_shash(\"sha256\", 0, 0);     if (IS_ERR(sha256))         return -1;       shash = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(sha256),                     GFP_KERNEL);     if (!shash)         return -ENOMEM;       shash->tfm = sha256;       if (crypto_shash_init(shash))         return -1;       if (crypto_shash_update(shash, plaintext, strlen(plaintext)))         return -1;       if (crypto_shash_final(shash, hash_sha256))         return -1;       kfree(shash);     crypto_free_shash(sha256);       show_hash_result(plaintext, hash_sha256);       return 0; }   static void cryptosha256_exit(void) { }   module_init(cryptosha256_init); module_exit(cryptosha256_exit);   MODULE_DESCRIPTION(\"sha256 hash test\"); MODULE_LICENSE(\"GPL\");<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043c\u043e\u0434\u0443\u043b\u044c:<\/p>\n<pre><code class=\"bash\">sudo insmod cryptosha256.ko sudo dmesg<\/code><\/pre>\n<p>  \u0418 \u0443\u0432\u0438\u0434\u0438\u0442\u0435, \u0447\u0442\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u0435\u0448.<\/p>\n<p>  \u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c:<\/p>\n<pre><code class=\"bash\">sudo rmmod cryptosha256<\/code><\/pre>\n<p>  <\/p>\n<h3><font color=\"#3AC1EF\">\u258d 16.2 \u0428\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441 \u0441\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u0447\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c<\/font><\/h3>\n<p>  \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u0447\u043d\u043e\u0433\u043e \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 AES \u0438 \u043f\u0430\u0440\u043e\u043b\u044f.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">cryptosk.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * cryptosk.c  *\/ #include &lt;crypto\/internal\/skcipher.h> #include &lt;linux\/crypto.h> #include &lt;linux\/module.h> #include &lt;linux\/random.h> #include &lt;linux\/scatterlist.h>   #define SYMMETRIC_KEY_LENGTH 32 #define CIPHER_BLOCK_SIZE 16   struct tcrypt_result {     struct completion completion;     int err; };   struct skcipher_def {     struct scatterlist sg;     struct crypto_skcipher *tfm;     struct skcipher_request *req;     struct tcrypt_result result;     char *scratchpad;     char *ciphertext;     char *ivdata; };   static struct skcipher_def sk;   static void test_skcipher_finish(struct skcipher_def *sk) {     if (sk->tfm)         crypto_free_skcipher(sk->tfm);     if (sk->req)         skcipher_request_free(sk->req);     if (sk->ivdata)         kfree(sk->ivdata);     if (sk->scratchpad)         kfree(sk->scratchpad);     if (sk->ciphertext)         kfree(sk->ciphertext); }   static int test_skcipher_result(struct skcipher_def *sk, int rc) {     switch (rc) {     case 0:         break;     case -EINPROGRESS || -EBUSY:         rc = wait_for_completion_interruptible(&amp;sk->result.completion);         if (!rc &amp;&amp; !sk->result.err) {             reinit_completion(&amp;sk->result.completion);             break;         }         pr_info(\"skcipher encrypt returned with %d result %d\\n\", rc,                 sk->result.err);         break;     default:         pr_info(\"skcipher encrypt returned with %d result %d\\n\", rc,                 sk->result.err);         break;     }       init_completion(&amp;sk->result.completion);       return rc; }   static void test_skcipher_callback(struct crypto_async_request *req, int error) {     struct tcrypt_result *result = req->data;       if (error == -EINPROGRESS)         return;       result->err = error;     complete(&amp;result->completion);     pr_info(\"Encryption finished successfully\\n\");       \/* \u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. *\/ #if 0     memset((void*)sk.scratchpad, '-', CIPHER_BLOCK_SIZE);     ret = crypto_skcipher_decrypt(sk.req);     ret = test_skcipher_result(&amp;sk, ret);     if (ret)         return;       sg_copy_from_buffer(&amp;sk.sg, 1, sk.scratchpad, CIPHER_BLOCK_SIZE);     sk.scratchpad[CIPHER_BLOCK_SIZE-1] = 0;       pr_info(\"Decryption request successful\\n\");     pr_info(\"Decrypted: %s\\n\", sk.scratchpad); #endif }   static int test_skcipher_encrypt(char *plaintext, char *password,                                  struct skcipher_def *sk) {     int ret = -EFAULT;     unsigned char key[SYMMETRIC_KEY_LENGTH];       if (!sk->tfm) {         sk->tfm = crypto_alloc_skcipher(\"cbc-aes-aesni\", 0, 0);         if (IS_ERR(sk->tfm)) {             pr_info(\"could not allocate skcipher handle\\n\");             return PTR_ERR(sk->tfm);         }     }       if (!sk->req) {         sk->req = skcipher_request_alloc(sk->tfm, GFP_KERNEL);         if (!sk->req) {             pr_info(\"could not allocate skcipher request\\n\");             ret = -ENOMEM;             goto out;         }     }       skcipher_request_set_callback(sk->req, CRYPTO_TFM_REQ_MAY_BACKLOG,                                   test_skcipher_callback, &amp;sk->result);       \/* \u041e\u0447\u0438\u0441\u0442\u043a\u0430 \u043a\u043b\u044e\u0447\u0430. *\/     memset((void *)key, '\\0', SYMMETRIC_KEY_LENGTH);       \/* \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0432 \u043c\u0438\u0440\u0435 \u043f\u0430\u0440\u043e\u043b\u044f. *\/     sprintf((char *)key, \"%s\", password);       \/* AES 256 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0441\u0438\u043c\u043c\u0435\u0442\u0440\u0438\u0447\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c. *\/     if (crypto_skcipher_setkey(sk->tfm, key, SYMMETRIC_KEY_LENGTH)) {         pr_info(\"key could not be set\\n\");         ret = -EAGAIN;         goto out;     }     pr_info(\"Symmetric key: %s\\n\", key);     pr_info(\"Plaintext: %s\\n\", plaintext);       if (!sk->ivdata) {         \/* \u0421\u043c. https:\/\/en.wikipedia.org\/wiki\/Initialization_vector *\/         sk->ivdata = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL);         if (!sk->ivdata) {             pr_info(\"could not allocate ivdata\\n\");             goto out;         }         get_random_bytes(sk->ivdata, CIPHER_BLOCK_SIZE);     }       if (!sk->scratchpad) {         \/* \u0422\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f. *\/         sk->scratchpad = kmalloc(CIPHER_BLOCK_SIZE, GFP_KERNEL);         if (!sk->scratchpad) {             pr_info(\"could not allocate scratchpad\\n\");             goto out;         }     }     sprintf((char *)sk->scratchpad, \"%s\", plaintext);       sg_init_one(&amp;sk->sg, sk->scratchpad, CIPHER_BLOCK_SIZE);     skcipher_request_set_crypt(sk->req, &amp;sk->sg, &amp;sk->sg, CIPHER_BLOCK_SIZE,                                sk->ivdata);     init_completion(&amp;sk->result.completion);       \/* \u0428\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. *\/     ret = crypto_skcipher_encrypt(sk->req);     ret = test_skcipher_result(sk, ret);     if (ret)         goto out;       pr_info(\"Encryption request successful\\n\");   out:     return ret; }   static int cryptoapi_init(void) {     \/* \u0421\u0430\u043c\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c \u0432 \u043c\u0438\u0440\u0435. *\/     char *password = \"password123\";       sk.tfm = NULL;     sk.req = NULL;     sk.scratchpad = NULL;     sk.ciphertext = NULL;     sk.ivdata = NULL;       test_skcipher_encrypt(\"Testing\", password, &amp;sk);     return 0; }   static void cryptoapi_exit(void) {     test_skcipher_finish(&amp;sk); }   module_init(cryptoapi_init); module_exit(cryptoapi_exit);   MODULE_DESCRIPTION(\"Symmetric key encryption example\"); MODULE_LICENSE(\"GPL\");<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h2><font color=\"#3AC1EF\">\u258d 17. \u0414\u0440\u0430\u0439\u0432\u0435\u0440 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430<\/font><\/h2>\n<p>  \u0414\u0440\u0430\u0439\u0432\u0435\u0440 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430 \u2013 \u044d\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u044c, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0438\u043b\u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0432\u0438\u0448\u0438, \u0441\u043e\u043e\u0431\u0449\u0430\u044f \u044f\u0434\u0440\u0443 \u043d\u0430\u0448\u0438 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438\u044f. \u0414\u0440\u0430\u0439\u0432\u0435\u0440 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430 \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0432\u0432\u043e\u0434\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>input_allocate_device()<\/code>, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0432 \u043d\u0435\u0439 \u0431\u0438\u0442\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f, ID \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0432\u0435\u0440\u0441\u0438\u044e \u0438 \u043f\u0440\u043e\u0447\u0435\u0435, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 <code>input_register_device()<\/code>.<\/p>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 <code>vinput<\/code> \u2013 API, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432. \u042d\u0442\u043e\u0442 \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>vinput_device()<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0438\u043c\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>vinput_ops<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442:<\/p>\n<ul>\n<li>\u0424\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438: <code>init()<\/code><\/li>\n<li>\u0424\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432\u0432\u043e\u0434\u0430: <code>send()<\/code><\/li>\n<li>\u0424\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f: <code>read()<\/code><\/li>\n<\/ul>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>vinput_register_device()<\/code> \u0438 <code>vinput_unregister_device()<\/code> \u043d\u043e\u0432\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u0432\u0432\u043e\u0434\u0430.<\/p>\n<pre><code class=\"cpp\">int init(struct vinput *);<\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f <code>struct vinput<\/code>, \u0443\u0436\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 <code>struct input_dev<\/code>. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>init()<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430 \u0438 \u0435\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e.<\/p>\n<pre><code class=\"cpp\">int send(struct vinput *, char *, int);<\/code><\/pre>\n<p>  \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u0432\u043d\u0435\u0434\u0440\u044f\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 <code>input_report_XXXX<\/code> \u0438\u043b\u0438 <code>input_event<\/code>. \u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0443\u0436\u0435 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<pre><code class=\"cpp\">int read(struct vinput *, char *, int);<\/code><\/pre>\n<p>  \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u0434\u043e\u043b\u0436\u043d\u0430 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0431\u0443\u0444\u0435\u0440\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0435\u043c, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e.<\/p>\n<p>  \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 <code>vinput<\/code> \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>sysfs<\/code>, \u0430 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0443\u0437\u0435\u043b <code>\/dev<\/code>. \u0418\u043c\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430.<\/p>\n<p>  \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>class_attribute<\/code> \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u043c \u0442\u0438\u043f\u0430\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0448\u043b\u0430 \u0440\u0435\u0447\u044c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 8:<\/p>\n<pre><code class=\"cpp\">struct class_attribute {     struct attribute attr;     ssize_t (*show)(struct class *class, struct class_attribute *attr,                     char *buf);     ssize_t (*store)(struct class *class, struct class_attribute *attr,                     const char *buf, size_t count); };<\/code><\/pre>\n<p>  \u0412 <code>vinput.c<\/code> \u043c\u0430\u043a\u0440\u043e\u0441 <code>CLASS_ATTR_WO(export\/unexport)<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0432 <code><a href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/stable\/linux.git\/tree\/include\/linux\/device.h\">include\/linux\/device.h<\/a><\/code> (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>device.h<\/code> \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u0432 <code><a href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/stable\/linux.git\/tree\/include\/linux\/input.h\">include\/linux\/input.h<\/a><\/code>) \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>class_attribut<\/code>e, \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0435 <code>class_attr_export\/unexport<\/code>. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442 \u0438\u0445 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 <code>vinput_class_attrs<\/code>, \u0438 \u043c\u0430\u043a\u0440\u043e\u0441 <code>ATTRIBUTE_GROUPS(vinput_class<\/code>) \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 <code>struct attribute_group vinput_class_group<\/code>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0432 <code>vinput_class<\/code>. \u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0437\u043e\u0432 <code>class_register(&amp;vinput_class)<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0432 <code>sysfs<\/code>.<\/p>\n<p>  \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 <code>sysfs vinputX<\/code> \u0438 \u0443\u0437\u043b\u0430 <code>\/dev<\/code>:<\/p>\n<pre><code class=\"cpp\">echo \"vkbd\" | sudo tee \/sys\/class\/vinput\/export<\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0443\u0436\u043d\u043e <code>echo<\/code> \u0435\u0433\u043e ID \u0432 <code>unexport<\/code>.<\/p>\n<pre><code class=\"cpp\">echo \"0\" | sudo tee \/sys\/class\/vinput\/unexport<\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">vinput.h<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\"> \/*  * vinput.h  *\/   #ifndef VINPUT_H #define VINPUT_H   #include &lt;linux\/input.h> #include &lt;linux\/spinlock.h>   #define VINPUT_MAX_LEN 128 #define MAX_VINPUT 32 #define VINPUT_MINORS MAX_VINPUT   #define dev_to_vinput(dev) container_of(dev, struct vinput, dev)   struct vinput_device;   struct vinput {     long id;     long devno;     long last_entry;     spinlock_t lock;       void *priv_data;       struct device dev;     struct list_head list;     struct input_dev *input;     struct vinput_device *type; };   struct vinput_ops {     int (*init)(struct vinput *);     int (*kill)(struct vinput *);     int (*send)(struct vinput *, char *, int);     int (*read)(struct vinput *, char *, int); };   struct vinput_device {     char name[16];     struct list_head list;     struct vinput_ops *ops; };   int vinput_register(struct vinput_device *dev); void vinput_unregister(struct vinput_device *dev);   #endif<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">vinput.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * vinput.c  *\/  #include &lt;linux\/cdev.h> #include &lt;linux\/input.h> #include &lt;linux\/module.h> #include &lt;linux\/slab.h> #include &lt;linux\/spinlock.h>   #include &lt;asm\/uaccess.h>   #include \"vinput.h\"   #define DRIVER_NAME \"vinput\"   #define dev_to_vinput(dev) container_of(dev, struct vinput, dev)   static DECLARE_BITMAP(vinput_ids, VINPUT_MINORS);   static LIST_HEAD(vinput_devices); static LIST_HEAD(vinput_vdevices);   static int vinput_dev; static struct spinlock vinput_lock; static struct class vinput_class;   \/* \u041f\u043e\u0438\u0441\u043a \u0438\u043c\u0435\u043d\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 vinput \u0432 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435 vinput_devices,  * \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c \u0432 vinput_register().  *\/ static struct vinput_device *vinput_get_device_by_type(const char *type) {     int found = 0;     struct vinput_device *vinput;     struct list_head *curr;       spin_lock(&amp;vinput_lock);     list_for_each (curr, &amp;vinput_devices) {         vinput = list_entry(curr, struct vinput_device, list);         if (vinput &amp;&amp; strncmp(type, vinput->name, strlen(vinput->name)) == 0) {             found = 1;             break;         }     }     spin_unlock(&amp;vinput_lock);       if (found)         return vinput;     return ERR_PTR(-ENODEV); }   \/* \u041f\u043e\u0438\u0441\u043a ID \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435 vinput_vdevices,  * \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c \u0432 vinput_alloc_vdevice().  *\/ static struct vinput *vinput_get_vdevice_by_id(long id) {     struct vinput *vinput = NULL;     struct list_head *curr;       spin_lock(&amp;vinput_lock);     list_for_each (curr, &amp;vinput_vdevices) {         vinput = list_entry(curr, struct vinput, list);         if (vinput &amp;&amp; vinput->id == id)             break;     }     spin_unlock(&amp;vinput_lock);       if (vinput &amp;&amp; vinput->id == id)         return vinput;     return ERR_PTR(-ENODEV); }   static int vinput_open(struct inode *inode, struct file *file) {     int err = 0;     struct vinput *vinput = NULL;       vinput = vinput_get_vdevice_by_id(iminor(inode));       if (IS_ERR(vinput))         err = PTR_ERR(vinput);     else         file->private_data = vinput;       return err; }   static int vinput_release(struct inode *inode, struct file *file) {     return 0; }   static ssize_t vinput_read(struct file *file, char __user *buffer, size_t count,                            loff_t *offset) {     int len;     char buff[VINPUT_MAX_LEN + 1];     struct vinput *vinput = file->private_data;       len = vinput->type->ops->read(vinput, buff, count);       if (*offset > len)         count = 0;     else if (count + *offset > VINPUT_MAX_LEN)         count = len - *offset;       if (raw_copy_to_user(buffer, buff + *offset, count))         count = -EFAULT;       *offset += count;       return count; }   static ssize_t vinput_write(struct file *file, const char __user *buffer,                             size_t count, loff_t *offset) {     char buff[VINPUT_MAX_LEN + 1];     struct vinput *vinput = file->private_data;       memset(buff, 0, sizeof(char) * (VINPUT_MAX_LEN + 1));       if (count > VINPUT_MAX_LEN) {         dev_warn(&amp;vinput->dev, \"Too long. %d bytes allowed\\n\", VINPUT_MAX_LEN);         return -EINVAL;     }       if (raw_copy_from_user(buff, buffer, count))         return -EFAULT;       return vinput->type->ops->send(vinput, buff, count); }   static const struct file_operations vinput_fops = {     .owner = THIS_MODULE,     .open = vinput_open,     .release = vinput_release,     .read = vinput_read,     .write = vinput_write, };   static void vinput_unregister_vdevice(struct vinput *vinput) {     input_unregister_device(vinput->input);     if (vinput->type->ops->kill)         vinput->type->ops->kill(vinput); }   static void vinput_destroy_vdevice(struct vinput *vinput) {     \/* \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430. *\/     spin_lock(&amp;vinput_lock);     list_del(&amp;vinput->list);     clear_bit(vinput->id, vinput_ids);     spin_unlock(&amp;vinput_lock);       module_put(THIS_MODULE);       kfree(vinput); }   static void vinput_release_dev(struct device *dev) {     struct vinput *vinput = dev_to_vinput(dev);     int id = vinput->id;       vinput_destroy_vdevice(vinput);       pr_debug(\"released vinput%d.\\n\", id); }   static struct vinput *vinput_alloc_vdevice(void) {     int err;     struct vinput *vinput = kzalloc(sizeof(struct vinput), GFP_KERNEL);       try_module_get(THIS_MODULE);       memset(vinput, 0, sizeof(struct vinput));       spin_lock_init(&amp;vinput->lock);       spin_lock(&amp;vinput_lock);     vinput->id = find_first_zero_bit(vinput_ids, VINPUT_MINORS);     if (vinput->id >= VINPUT_MINORS) {         err = -ENOBUFS;         goto fail_id;     }     set_bit(vinput->id, vinput_ids);     list_add(&amp;vinput->list, &amp;vinput_vdevices);     spin_unlock(&amp;vinput_lock);       \/* \u0412\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430. *\/     vinput->input = input_allocate_device();     if (vinput->input == NULL) {         pr_err(\"vinput: Cannot allocate vinput input device\\n\");         err = -ENOMEM;         goto fail_input_dev;     }       \/* \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430. *\/     vinput->dev.class = &amp;vinput_class;     vinput->dev.release = vinput_release_dev;     vinput->dev.devt = MKDEV(vinput_dev, vinput->id);     dev_set_name(&amp;vinput->dev, DRIVER_NAME \"%lu\", vinput->id);       return vinput;   fail_input_dev:     spin_lock(&amp;vinput_lock);     list_del(&amp;vinput->list); fail_id:     spin_unlock(&amp;vinput_lock);     module_put(THIS_MODULE);     kfree(vinput);       return ERR_PTR(err); }   static int vinput_register_vdevice(struct vinput *vinput) {     int err = 0;       \/* \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430. *\/     vinput->input->name = vinput->type->name;     vinput->input->phys = \"vinput\";     vinput->input->dev.parent = &amp;vinput->dev;       vinput->input->id.bustype = BUS_VIRTUAL;     vinput->input->id.product = 0x0000;     vinput->input->id.vendor = 0x0000;     vinput->input->id.version = 0x0000;       err = vinput->type->ops->init(vinput);       if (err == 0)         dev_info(&amp;vinput->dev, \"Registered virtual input %s %ld\\n\",                  vinput->type->name, vinput->id);       return err; }   static ssize_t export_store(struct class *class, struct class_attribute *attr,                             const char *buf, size_t len) {     int err;     struct vinput *vinput;     struct vinput_device *device;       device = vinput_get_device_by_type(buf);     if (IS_ERR(device)) {         pr_info(\"vinput: This virtual device isn't registered\\n\");         err = PTR_ERR(device);         goto fail;     }       vinput = vinput_alloc_vdevice();     if (IS_ERR(vinput)) {         err = PTR_ERR(vinput);         goto fail;     }       vinput->type = device;     err = device_register(&amp;vinput->dev);     if (err &lt; 0)         goto fail_register;       err = vinput_register_vdevice(vinput);     if (err &lt; 0)         goto fail_register_vinput;       return len;   fail_register_vinput:     device_unregister(&amp;vinput->dev); fail_register:     vinput_destroy_vdevice(vinput); fail:     return err; } \/* \u042d\u0442\u043e\u0442 \u043c\u0430\u043a\u0440\u043e\u0441 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 class_attr_export \u0438 export_store() *\/ static CLASS_ATTR_WO(export);   static ssize_t unexport_store(struct class *class, struct class_attribute *attr,                               const char *buf, size_t len) {     int err;     unsigned long id;     struct vinput *vinput;       err = kstrtol(buf, 10, &amp;id);     if (err) {         err = -EINVAL;         goto failed;     }       vinput = vinput_get_vdevice_by_id(id);     if (IS_ERR(vinput)) {         pr_err(\"vinput: No such vinput device %ld\\n\", id);         err = PTR_ERR(vinput);         goto failed;     }       vinput_unregister_vdevice(vinput);     device_unregister(&amp;vinput->dev);       return len; failed:     return err; } \/* \u042d\u0442\u043e\u0442 \u043c\u0430\u043a\u0440\u043e\u0441 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 class_attr_unexport  * \u0438 unexport_store().  *\/ static CLASS_ATTR_WO(unexport);   static struct attribute *vinput_class_attrs[] = {     &amp;class_attr_export.attr,     &amp;class_attr_unexport.attr,     NULL, };   \/* \u042d\u0442\u043e\u0442 \u043c\u0430\u043a\u0440\u043e\u0441 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 vinput_class_groups. *\/ ATTRIBUTE_GROUPS(vinput_class);   static struct class vinput_class = {     .name = \"vinput\",     .owner = THIS_MODULE,     .class_groups = vinput_class_groups, };   int vinput_register(struct vinput_device *dev) {     spin_lock(&amp;vinput_lock);     list_add(&amp;dev->list, &amp;vinput_devices);     spin_unlock(&amp;vinput_lock);       pr_info(\"vinput: registered new virtual input device '%s'\\n\", dev->name);       return 0; } EXPORT_SYMBOL(vinput_register);   void vinput_unregister(struct vinput_device *dev) {     struct list_head *curr, *next;       \/* \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430. *\/     spin_lock(&amp;vinput_lock);     list_del(&amp;dev->list);     spin_unlock(&amp;vinput_lock);       \/* \u0421\u043d\u044f\u0442\u0438\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430. *\/     list_for_each_safe (curr, next, &amp;vinput_vdevices) {         struct vinput *vinput = list_entry(curr, struct vinput, list);         if (vinput &amp;&amp; vinput->type == dev) {             vinput_unregister_vdevice(vinput);             device_unregister(&amp;vinput->dev);         }     }       pr_info(\"vinput: unregistered virtual input device '%s'\\n\", dev->name); } EXPORT_SYMBOL(vinput_unregister);   static int __init vinput_init(void) {     int err = 0;       pr_info(\"vinput: Loading virtual input driver\\n\");       vinput_dev = register_chrdev(0, DRIVER_NAME, &amp;vinput_fops);     if (vinput_dev &lt; 0) {         pr_err(\"vinput: Unable to allocate char dev region\\n\");         goto failed_alloc;     }       spin_lock_init(&amp;vinput_lock);       err = class_register(&amp;vinput_class);     if (err &lt; 0) {         pr_err(\"vinput: Unable to register vinput class\\n\");         goto failed_class;     }       return 0; failed_class:     class_unregister(&amp;vinput_class); failed_alloc:     return err; }   static void __exit vinput_end(void) {     pr_info(\"vinput: Unloading virtual input driver\\n\");       unregister_chrdev(vinput_dev, DRIVER_NAME);     class_unregister(&amp;vinput_class); }   module_init(vinput_init); module_exit(vinput_end);   MODULE_LICENSE(\"GPL\"); MODULE_DESCRIPTION(\"Emulate input events\");<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0443 \u043a\u0430\u043a \u043e\u0434\u0438\u043d \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>vinput<\/code>. \u041e\u043d\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u043a\u043e\u0434\u044b \u043a\u043b\u0430\u0432\u0438\u0448 <code>KEY_MAX<\/code>. \u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>KEY_CODE<\/code>, \u043a\u0430\u043a \u044d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0432 <code><a href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/stable\/linux.git\/tree\/include\/linux\/input.h\">include\/linux\/input.h<\/a><\/code>. \u041f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 <code>KEY_PRESS<\/code>, \u0430 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 <code>KEY_RELEASE<\/code>. \u042d\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0435 \u0432\u0432\u043e\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430\u0436\u0430\u0442\u043e\u0439 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. \u041a\u043e\u0434 \u043d\u0438\u0436\u0435 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>  \u0421\u0438\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u00abg\u00bb ( <code>KEY_G = 34<\/code>):<\/p>\n<pre><code class=\"cpp\">echo \"+34\" | sudo tee \/dev\/vinput0<\/code><\/pre>\n<p>  \u0421\u0438\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0435 \u00abg\u00bb ( <code>KEY_G = 34<\/code>):<\/p>\n<pre><code class=\"cpp\">echo \"-34\" | sudo tee \/dev\/vinput0<\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">vkbd.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * vkbd.c  *\/   #include &lt;linux\/init.h> #include &lt;linux\/input.h> #include &lt;linux\/module.h> #include &lt;linux\/spinlock.h>   #include \"vinput.h\"   #define VINPUT_KBD \"vkbd\" #define VINPUT_RELEASE 0 #define VINPUT_PRESS 1   static unsigned short vkeymap[KEY_MAX];   static int vinput_vkbd_init(struct vinput *vinput) {     int i;       \/* \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0431\u0438\u0442\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u0432\u0432\u043e\u0434\u0430. *\/     vinput->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);     vinput->input->keycodesize = sizeof(unsigned short);     vinput->input->keycodemax = KEY_MAX;     vinput->input->keycode = vkeymap;       for (i = 0; i &lt; KEY_MAX; i++)         set_bit(vkeymap[i], vinput->input->keybit);       \/* vinput \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430 \u0447\u0435\u0440\u0435\u0437      * input_allocate_device(), \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441 \u043b\u0451\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u0435\u0433\u043e      * \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c.      *\/     return input_register_device(vinput->input); }   static int vinput_vkbd_read(struct vinput *vinput, char *buff, int len) {     spin_lock(&amp;vinput->lock);     len = snprintf(buff, len, \"%+ld\\n\", vinput->last_entry);     spin_unlock(&amp;vinput->lock);       return len; }   static int vinput_vkbd_send(struct vinput *vinput, char *buff, int len) {     int ret;     long key = 0;     short type = VINPUT_PRESS;       \/* \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u043a\u0430\u043a\u043e\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435      * (\u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u0438\u043b\u0438 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u0435) \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u044d\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.      *\/     if (buff[0] == '+')         ret = kstrtol(buff + 1, 10, &amp;key);     else         ret = kstrtol(buff, 10, &amp;key);     if (ret)         dev_err(&amp;vinput->dev, \"error during kstrtol: -%d\\n\", ret);     spin_lock(&amp;vinput->lock);     vinput->last_entry = key;     spin_unlock(&amp;vinput->lock);       if (key &lt; 0) {         type = VINPUT_RELEASE;         key = -key;     }       dev_info(&amp;vinput->dev, \"Event %s code %ld\\n\",              (type == VINPUT_RELEASE) ? \"VINPUT_RELEASE\" : \"VINPUT_PRESS\", key);       \/* \u041f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0432\u0432\u043e\u0434\u0430. *\/     input_report_key(vinput->input, key, type);     \/* \u0421\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0432\u0432\u043e\u0434\u0430, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u0430. *\/     input_sync(vinput->input);       return len; }   static struct vinput_ops vkbd_ops = {     .init = vinput_vkbd_init,     .send = vinput_vkbd_send,     .read = vinput_vkbd_read, };   static struct vinput_device vkbd_dev = {     .name = VINPUT_KBD,     .ops = &amp;vkbd_ops, };   static int __init vkbd_init(void) {     int i;       for (i = 0; i &lt; KEY_MAX; i++)         vkeymap[i] = i;     return vinput_register(&amp;vkbd_dev); }   static void __exit vkbd_end(void) {     vinput_unregister(&amp;vkbd_dev); }   module_init(vkbd_init); module_exit(vkbd_end);   MODULE_LICENSE(\"GPL\"); MODULE_DESCRIPTION(\"Emulate keyboard input events through \/dev\/vinput\");<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h2><font color=\"#3AC1EF\">\u258d 18. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432: \u043c\u043e\u0434\u0435\u043b\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430<\/font><\/h2>\n<p>  \u041a \u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0432\u0441\u0435 \u0432\u0438\u0434\u044b \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0435 \u0432\u0441\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043d\u043e \u0432 \u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u0445 \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u044f\u0434\u0440\u0430. \u0414\u043b\u044f \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u043b\u0430 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c, \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0438 \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430. \u041d\u0438\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u0435\u0451 \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0447\u0435\u0433\u043e.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">devicemodel.c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * devicemodel.c  *\/ #include &lt;linux\/kernel.h> #include &lt;linux\/module.h> #include &lt;linux\/platform_device.h>   struct devicemodel_data {     char *greeting;     int number; };   static int devicemodel_probe(struct platform_device *dev) {     struct devicemodel_data *pd =         (struct devicemodel_data *)(dev->dev.platform_data);       pr_info(\"devicemodel probe\\n\");     pr_info(\"devicemodel greeting: %s; %d\\n\", pd->greeting, pd->number);       \/* \u041a\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430. *\/       return 0; }   static int devicemodel_remove(struct platform_device *dev) {     pr_info(\"devicemodel example removed\\n\");       \/* \u041a\u043e\u0434 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430. *\/       return 0; }   static int devicemodel_suspend(struct device *dev) {     pr_info(\"devicemodel example suspend\\n\");       \/* \u041a\u043e\u0434 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430. *\/       return 0; }   static int devicemodel_resume(struct device *dev) {     pr_info(\"devicemodel example resume\\n\");       \/* \u041a\u043e\u0434 \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430. *\/       return 0; }   static const struct dev_pm_ops devicemodel_pm_ops = {     .suspend = devicemodel_suspend,     .resume = devicemodel_resume,     .poweroff = devicemodel_suspend,     .freeze = devicemodel_suspend,     .thaw = devicemodel_resume,     .restore = devicemodel_resume, };   static struct platform_driver devicemodel_driver = {     .driver =         {             .name = \"devicemodel_example\",             .owner = THIS_MODULE,             .pm = &amp;devicemodel_pm_ops,         },     .probe = devicemodel_probe,     .remove = devicemodel_remove, };   static int devicemodel_init(void) {     int ret;       pr_info(\"devicemodel init\\n\");       ret = platform_driver_register(&amp;devicemodel_driver);       if (ret) {         pr_err(\"Unable to register driver\\n\");         return ret;     }       return 0; }   static void devicemodel_exit(void) {     pr_info(\"devicemodel exit\\n\");     platform_driver_unregister(&amp;devicemodel_driver); }   module_init(devicemodel_init); module_exit(devicemodel_exit);   MODULE_LICENSE(\"GPL\"); MODULE_DESCRIPTION(\"Linux Device Model example\"); <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h2><font color=\"#3AC1EF\">19. \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438<\/font><\/h2>\n<p>  <\/p>\n<h3><font color=\"#3AC1EF\">\u258d 19.1 \u0423\u0441\u043b\u043e\u0432\u0438\u044f likely \u0438 unlikely<\/font><\/h3>\n<p>  \u0418\u043d\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u043e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0435\u0447\u0442\u043e, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0435 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443. \u0415\u0441\u043b\u0438 \u0432\u0430\u0448 \u043a\u043e\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f, \u0438 \u0432\u044b \u0437\u043d\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u044d\u0442\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a <code>true<\/code> \u043b\u0438\u0431\u043e <code>false<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 <code>likely<\/code> \u0438 <code>unlikely<\/code>. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043f\u0440\u0438 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"cpp\">bvl = bvec_alloc(gfp_mask, nr_iovecs, &amp;idx); if (unlikely(!bvl)) {     mempool_free(bio, bio_pool);     bio = NULL;     goto out; }<\/code><\/pre>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0430\u043a\u0440\u043e\u0441 <code>unlikely<\/code>, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 \u0432\u044b\u0432\u043e\u0434 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u0434 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u043b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u043e \u0432\u0435\u0442\u043a\u0435 <code>false<\/code> \u0438 \u0434\u0435\u043b\u0430\u043b \u043f\u0435\u0440\u0435\u0445\u043e\u0434, \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0433\u0434\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 <code>true<\/code>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430. \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u0430 <code>likely<\/code> \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u043e\u0435.<\/p>\n<h2><font color=\"#3AC1EF\">20. \u0412\u0430\u0436\u043d\u044b\u0435 \u043d\u044e\u0430\u043d\u0441\u044b<\/font><\/h2>\n<p>  <\/p>\n<h3><font color=\"#3AC1EF\">\u258d 20.1 \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a<\/font><\/h3>\n<p>  \u042d\u0442\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f. \u0412 \u043c\u043e\u0434\u0443\u043b\u0435 \u044f\u0434\u0440\u0430 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u044f\u0434\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0432 <code>\/proc\/kallsyms<\/code>.<\/p>\n<h3><font color=\"#3AC1EF\">\u258d 20.2 \u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439<\/font><\/h3>\n<p>  \u0412\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0435\u043d\u0430\u0434\u043e\u043b\u0433\u043e, \u0447\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u044b \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0438\u0445 \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435, \u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\u0432\u0438\u0441\u043d\u0435\u0442, \u0438 \u0435\u0451 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c.<\/p>\n<h2><font color=\"#3AC1EF\">\u258d 21. \u0414\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 \u0448\u0430\u0433\u0438<\/font><\/h2>\n<p>  \u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d \u0432 \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f\u0434\u0440\u0430, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u043c <a href=\"https:\/\/kernelnewbies.org\/\">kernelnewbies.org<\/a> \u0438 \u043f\u043e\u0434\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0435\u0439 <a href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/stable\/linux.git\/tree\/Documentation\">Documentation<\/a> \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u0430\u0451\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u0438\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043c\u044b, \u0445\u043e\u0442\u044f \u043c\u0435\u0441\u0442\u0430\u043c\u0438 \u043c\u043e\u0433\u043b\u0430 \u0431\u044b \u0431\u044b\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0448\u0435. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u043b \u0441\u0430\u043c \u041b\u0438\u043d\u0443\u0441 \u0422\u043e\u0440\u0432\u0430\u043b\u044c\u0434\u0441, \u043b\u0443\u0447\u0448\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u044f\u0434\u0440\u043e \u2013 \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u0432\u043d\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u0432 \u0434\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u0441\u043e\u0431\u0438\u0435 \u0438\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u0432 \u043d\u0451\u043c \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0435 \u043d\u0435\u0434\u043e\u0447\u0451\u0442\u044b, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043f\u043e \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 <a href=\"https:\/\/github.com\/sysprog21\/lkmpg\">https:\/\/github.com\/sysprog21\/lkmpg<\/a>. \u0411\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u0435\u043b\u044c\u043d\u044b \u0437\u0430 \u0432\u0430\u0448\u0438 \u043f\u0443\u043b-\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u044b.<\/p>\n<p>  \u0423\u0441\u043f\u0435\u0445\u043e\u0432!<\/p>\n<blockquote><p><b><font color=\"#3AC1EF\"><a href=\"https:\/\/bit.ly\/3KZeaxv\">Telegram-\u043a\u0430\u043d\u0430\u043b<\/a> \u0438 <a href=\"https:\/\/bit.ly\/3qoIOXs\">\u0443\u044e\u0442\u043d\u044b\u0439 \u0447\u0430\u0442<\/a> \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432<\/font><\/b><\/p><\/blockquote>\n<p><a href=\"http:\/\/ruvds.com\/ru-rub?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=Bright_Translate&amp;utm_content=posobie_po_programmirovaniyu_modulej_yadra_linux_ch_7\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/sz\/7j\/pf\/sz7jpfj8i1pa6ocj-eia09dev4q.png\" data-src=\"https:\/\/habrastorage.org\/webt\/sz\/7j\/pf\/sz7jpfj8i1pa6ocj-eia09dev4q.png\"\/><\/a><\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/689346\/\"> https:\/\/habr.com\/ru\/company\/ruvds\/blog\/689346\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><a href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/688564\/\"><\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/-7\/yl\/hp\/-7ylhpzc6raohz-vopxottyejfu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/-7\/yl\/hp\/-7ylhpzc6raohz-vopxottyejfu.png\"\/><\/div>\n<p><\/a><br \/>  \u0417\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u044f\u0434\u0440\u0430 \u043e\u0442 02 \u0438\u044e\u043b\u044f 2022 \u0433\u043e\u0434\u0430. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439, \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044e, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0434\u0435\u043b\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0432\u0432\u043e\u0434\u0430 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438. \u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0436\u0435 \u044f \u0443\u043a\u0430\u0436\u0443 \u043d\u0430 \u043f\u0430\u0440\u0443 \u043d\u0435\u044f\u0432\u043d\u044b\u0445, \u043d\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u043d\u044e\u0430\u043d\u0441\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u043f\u043e \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c\u0443 \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u044e \u0432 \u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f\u0434\u0440\u0430.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-338674","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=338674"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/338674\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=338674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=338674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=338674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}