{"id":20612351,"url":"https://github.com/ralienpp/hello-kernel","last_synced_at":"2026-04-22T07:33:32.441Z","repository":{"id":144817839,"uuid":"104450634","full_name":"ralienpp/hello-kernel","owner":"ralienpp","description":"Basic kernel-mode module and a user-mode application that interacts with it.","archived":false,"fork":false,"pushed_at":"2018-09-03T08:26:35.000Z","size":15,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-17T03:36:23.469Z","etag":null,"topics":["character-devices","ioctl","linux-kernel"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ralienpp.png","metadata":{"files":{"readme":"readme.rst","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-22T08:27:00.000Z","updated_at":"2024-02-23T10:54:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"e29800e7-272a-4d79-8f6a-cc10a5965c4b","html_url":"https://github.com/ralienpp/hello-kernel","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ralienpp%2Fhello-kernel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ralienpp%2Fhello-kernel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ralienpp%2Fhello-kernel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ralienpp%2Fhello-kernel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ralienpp","download_url":"https://codeload.github.com/ralienpp/hello-kernel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242259922,"owners_count":20098429,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["character-devices","ioctl","linux-kernel"],"created_at":"2024-11-16T10:24:07.870Z","updated_at":"2026-04-22T07:33:27.361Z","avatar_url":"https://github.com/ralienpp.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"Overview\n========\n\nThis is a basic kernel module that implements the following features:\n\n- entry point for loading and unloading the kernel module\n- debug statements that can be observed with ``dmesg``\n- optionally transmitting a parameter, ``magic``, when the module is loaded (otherwise a default value is used)\n- creation of a character device, ``/dev/oracle`` (mknod must be invoked manually for now)\n- implements the ``read`` API, which takes the current value of ``magic`` and copies it from the kernel to the user-space buffer\n- reacts to any ``ioctl`` sent to the module by incrementing ``magic``\n\n\nInstructions\n============\n\nThis was tested on Debian 7 x64.\n\nPrerequisites\n-------------\n\nThis only needs to be done once, to prepare the compilation environment.\n\n- ``sudo apt-get install build-essentials``\n- ``sudo apt-get install linux-headers-$(uname -r)``\n\nIt is expected that you already have Python, it will be needed for the user-mode program to test ``ioctl`` handling.\n\nCompilation\n-----------\n\nGet into the directory where you cloned the git repo and run ``make``. The output will be stored in ``hellok.ko``.\n\n#. ``git clone https://github.com/ralienpp/hello-kernel.git``\n#. ``cd hello-kernel``\n#. ``make``\n\n\nBasic test\n----------\n\nYou can make sure this loads and unloads correctly as follows:\n\n#. ``sudo insmod ./hellok.ko``\n#. run ``lsmod`` and it should be in the list of loaded modules, e.g. ::\n\n\tModule                  Size  Used by\n\thellok                 12452  0\n\n#. unload it with ``sudo rmmod hellok``\n#. run ``dmesg`` to see what has just happened, the debug lines should be there::\n\n\t[73964.820487] hellok: module license 'unspecified' taints kernel.\n\t[73964.820492] Disabling lock debugging due to kernel taint\n\t[74342.727012] Loaded hellok\n\t[74469.278069] Unloaded hellok\n\nNotes on parameters\n~~~~~~~~~~~~~~~~~~~\n\n- You can pass a parameter at load time, e.g. ``sudo insmod ./hellok.ko magic=12``. If not specified, a default value will be used.\n- The value can be examined after the module is loaded: ``cat /sys/module/hellok/parameters/magic``\n- You can write to it (if permissions allow so), e.g. (as root) ``echo 45 \u003e /sys/module/hellok/parameters/magic``\n\n\nCharacter-device operations\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo check if the devices was created successfully, run ``cat /proc/devices`` and expect something like this::\n\n\tCharacter devices:\n\t100 Oracle\n\nThe number is the ``MAJOR`` defined in the code, and the name is the string we used to name the device.\n\nBefore you can interact with this device, run ``sudo mknod -m 666 /dev/oracle c 100 0`` (create a character device, allowing everyone to do everything with it, 100 is ``MAJOR`` as defined in the code, and 0 is the minor [taken \"as is\" from a guide]).\n\nUser-mode tool\n==============\n\nTo demonstrate communication between kernel-space and user-space, you can run ``cat /dev/oracle`` and the value of ``magic`` will be shown on the screen as a string.\n\nThis happens by copying this value from a buffer in the kernel's address space, into a buffer in user-space, using ``copy_to_user``.\n\n\nAlternatively, run ``python testusermode.py``, which will send an ``ioctl`` to ``/dev/oracle`` (the driver doesn't care what command is sent, they're all handled equally). You can observe the effect by reading from ``/dev/oracle``, the read value should be incremeted after each ioctl call.\n\n\n\nReferences\n==========\n\n- http://www.tldp.org/LDP/lkmpg/2.4/html/x281.htm\n- https://www.apriorit.com/dev-blog/195-simple-driver-for-linux-os\n- https://www.youtube.com/watch?v=Zn8mEZXr6nE\n- http://www.virtsync.com/c-error-codes-include-errno\n- https://lwn.net/Articles/115651/\n\n\n\nQuestions\n=========\n\n#. why ``static``? Other tutorials don't have that.\n#. what is the point of having major and minor versions?\n#. can ``mknod`` be invoked automatically?\n#. ``cat`` never stops, should I add an ``EOF`` at the end? (does stop when run as root, strange)\n#. ``#define ENOTTY      25  /* Not a typewriter */`` why can't my character device handle this?\n#. what is a safe way to avoid ``MAJOR`` collisions?\n\n\n\nNote to self\n============\n\n- use ``%zu`` for ``size_t`` in debug statements\n\n\n\n\nReasoning\n=========\n\n- ``ioctl`` is used because I was aware of this concept earlier and expected it to be easier. After reading more about it while implementing it, I found it convenient that I can send a ``void`` payload, and use the presence of the message itself as a signal, which is sufficient for the purposes of this prototype. Otherwise, the benefit of the ``ioctl`` is that it provides the possibility to send arbitrary payloads, which may be handy in the future.\n- clearly, the communication done via ``/sys/module/hellok/parameters/magic`` is another form of interaction between kernel-space and user-space, which is not an ``ioctl`` and which appears to be a much simpler/cheaper method, because I got it \"for free\" (no need to write a handler for it).\n- when it comes to user-space, the \"cheapest\" way to prove it works is to read from ``/dev/oracle`` with any existing tool, thus there's no need to write any code at all.\n- however, I also wrote a Python program in order to check how the ``ioctl`` handler works. I used this language because it was much easier to write in, and I was thinking that if there were implementation issues it would be easier to debug them using the REPL. However, due to the simplicity of the current driver, there's not much room for something not to work.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fralienpp%2Fhello-kernel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fralienpp%2Fhello-kernel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fralienpp%2Fhello-kernel/lists"}