Search logs:

channel logs for 2004 - 2010 are archived at http://tunes.org/~nef/logs/old/ ·· can't be searched

#osdev2 = #osdev @ Libera from 23may2021 to present

#osdev @ OPN/FreeNode from 3apr2001 to 23may2021

all other channels are on OPN/FreeNode from 2004 to present


http://bespin.org/~qz/search/?view=1&c=osdev&y=19&m=5&d=21

Tuesday, 21 May 2019

12:07:13 <catern> is there a good alternative word for reading memory than "read"? I'm already using "read" for reading from file descriptors and it would be nice to not use the same word
12:07:27 <catern> load, perhaps? but that doesn't seem as clear
12:08:30 <Kazinsal> Not really. Welcome to computer science, we overload basically every term
12:20:19 <ZombieChicken> Kazinsal: We don't overload every term. Some terms are so poorly defined that they are meaningless to begin wtih
12:22:22 <Kazinsal> And some terms were defined so long ago that they're colloquial references to something commonly in use at the time but obsolete enough now that even most CS people have never heard of it
12:22:48 * _mjg looks at core
12:22:56 <Kazinsal> That was one of my first thoughts
12:23:29 <ZombieChicken> catern: Maybe use
12:23:31 <ZombieChicken> bah
12:23:54 <Kazinsal> Most modern OS janitors know what dumping core is, or have heard it before, and some may know what a core file is, but few know what core means and fewer still know where it comes from
12:23:58 <ZombieChicken> catern: Maybe use 'load' for reading a file and 'read' to get something from memory?
12:24:30 <catern> ZombieChicken: hmm, I want to reserve `read` for files since it's unixy
12:24:50 <catern> i originally thought you were proposing `use` though
12:25:06 <ZombieChicken> catern: imo, it makes more sense to me to load a file than read a file
12:25:17 <catern> which is an interesting suggestion even if it wasn't what you meant
12:25:31 <ZombieChicken> 'use' is a pretty nebulous term
12:25:40 <catern> yes, true
12:25:52 <ZombieChicken> Kazinsal: Core is the old "magnets on a conductive grid" memory, right?
12:26:03 <Kazinsal> Yeah
12:26:25 <ZombieChicken> wonder if that would work for the current FRAM that whatsit is making
12:26:51 <ZombieChicken> since I think both retain data over power cycles
12:27:15 <Kazinsal> I don't know what the highest density you can feasibly do with core
12:27:41 <ZombieChicken> old core memory was pretty low density
12:27:59 <Kazinsal> It's probably a lot higher now than it was in the early 70s when core started to go away but even then they were having issues less with making the parts smaller and more with putting the smallest parts together
12:28:02 <ZombieChicken> FRAM is, I think, a bit sparse wrt bits-per-mm
12:28:22 <ZombieChicken> compared to current RAM
12:28:35 <Kazinsal> Core is pretty neat though, it's non-volatile and somewhat EMP resistant
12:28:56 <ZombieChicken> FRAM is nonvolatile
12:29:03 <ZombieChicken> unless I'm thinking of the wrong acronym
12:29:09 <Kazinsal> The core on board the Challenger's flight computer kept its contents even after the orbiter disintegrated
12:29:27 <Kazinsal> So it can also take serious shock and water penetration
12:29:39 <ZombieChicken> yeah, FRAM is what I think it is
12:29:51 <ZombieChicken> https://en.wikipedia.org/wiki/Ferroelectric_RAM
12:30:24 <Kazinsal> Yeah that's basically the modern equivalent of magnetic core
12:30:39 <ZombieChicken> yeah
12:30:55 <ZombieChicken> it's one of those things that I'd love to see get more love than it currently does
12:31:07 <doug16k> so far I've only seen FRAM in tens of KB at a time on microcontroller
12:31:34 <Kazinsal> Mmhmm
12:31:46 <ZombieChicken> KB == kilobits or kilobytes? I never can keep that straight
12:31:59 <Kazinsal> Capital B is bytes, lowercase b is bits
12:32:02 <doug16k> usually capital is byte
12:32:05 <Kazinsal> Densest FRAM module I think is 8Mbit
12:32:17 <Kazinsal> And that's a relatively recent achievement
12:32:30 <ZombieChicken> 10s of KB is still a reasonable amount of memory for some applications
12:33:22 <doug16k> ya, 16KB is approaching infinite ram for some microcontroller applications
12:34:06 <ZombieChicken> and the (likely) insta-on you'd get from using RAM as persistant storage would have some advantages
12:35:10 <Kazinsal> Yeah at that point your biggest concern is getting your hardware back into the same state that your system is expecting it to be in
12:35:34 <doug16k> claimed 10^15 write cycle endurance on TI MSP430 MCUs
12:36:06 <Kazinsal> FRAM is one of those things that for me falls under the category of "would be really cool to have but unlikely to even be available outside of bespoke hardware"
12:36:34 <Kazinsal> similar to TCAM and whitebox ethernet switching ASICs
12:36:58 <ZombieChicken> TCAM? Never heard that before
12:37:13 <ZombieChicken> https://en.wikipedia.org/wiki/Ternary_content-addressable_memory <- That?
12:37:19 <Kazinsal> Yeah
12:38:19 <ZombieChicken> Interesting
12:38:34 <ZombieChicken> There was also this https://en.wikipedia.org/wiki/Telecommunications_Access_Method
12:39:22 <ZombieChicken> doug16k: that 10^15 write cycles is for FRAM?
12:39:27 <doug16k> ya
12:40:06 <doug16k> claimed 125ns per word write throughput (4ms/64KB)
12:40:27 <doug16k> beefy ones -> http://www.ti.com/document-viewer/MSP430FR5964/datasheet/device-overview-slase547447#SLASE547447
12:42:05 <ZombieChicken> Hmm. Wonder what the read time is
01:14:27 <doug16k> ZombieChicken, here's a TI FRAM FAQ -> http://www.ti.com/pub/fram/fram_faq.html
01:14:49 <doug16k> says basically reads include a write, since it must write back read values to refresh
01:25:33 <doug16k> @ 4GHz, 125ns is about 500 cycles
01:29:54 <doug16k> ah, faq claims 50ns available, @4GHz that is 200 cycles
01:30:55 <catern> if you saw a low-level library mention "the builder pattern", would you get a sour taste in your mouth?
01:31:04 <doug16k> no
01:31:14 <doug16k> nothing wrong with patterns when they fit well
01:32:19 <doug16k> if nothing else it quickly communicates what they expect the caller to do
01:44:46 <catern> ok then I guess I will use that phrase
02:39:33 <adu> I've seen a builder pattern implementation of printf
06:30:08 <catern> is it true that running commands on the VMS command line just invoked various entry points of normal system libraries?
06:30:46 <catern> like, instead of having each binary with a main as we do now, you could have a library with a bunch of entry points to provide different utilities, and also load that library into memory
06:31:01 <catern> and if so, where could I read more about that
06:31:40 <ZombieChicken> sounds like a good idea to me
06:33:52 <bcos> catern: Sounds unlikely - where did you get the impression VMS does this from in the first place?
06:34:21 <catern> bcos: it's a vague recollection from talking to a VMS expert in the past
06:34:22 <bcos> (sound like a horribly distorted description of "inbuilt shell commands")
06:34:43 <catern> well, I believe VMS did habitually have multiple entry points for libraries, since I could find that on google
06:35:07 <bcos> Libraries don't have entry points. That's what makes them libraries
06:36:01 <catern> that's false even on Linux ¯\_(ツ)_/¯
06:36:05 <bcos> ?
06:36:26 <catern> you can have a library with a main()
06:36:47 <catern> (which you can exec)
06:36:53 <bcos> Sure, but in that case your "main()" will just be an exported symbol like all the other exported symbols and won't be an entry point
06:37:00 <catern> not so
06:37:16 <bcos> If you can exec it, it's not a library
06:37:53 <catern> the classic example is ld.so
06:39:02 <bcos> ?
06:39:14 <clever> catern: i have noticed, that dlopen will refuse to import something tagged as an "executable"
06:40:24 <clever> because of that, i had to implement my own dlopen-ish function to handle that
06:40:27 <catern> https://unix.stackexchange.com/questions/223385/why-and-how-are-some-shared-libraries-runnable-as-though-they-are-executables
06:41:10 <zid> -r dynamic ftw
06:41:56 <zid> I've used it a bit for providing an API to modules I will later load
06:42:09 <clever> zid: was dealing with pre-existing kernels, that i was abusing via dlopen
06:42:11 <zid> rather than having to give them a bunch of function pointers in the init function
06:44:23 <bcos> catern: Looks like a hideous hack to work around the "can't dynamically link the dynamic linker" problem that shouldn't be supported.
06:46:46 <bcos> (things were much cleaner in the past - you'd have a toolchain specific "who cares what it is" object file format; then a completely different executable file format; with no confusion and no hackery and no vendor lock-in for the toolchain)
06:47:30 <mquy90> bcos, as you suggested, I read and wrote this pci https://github.com/MQuy/mos/blob/master/src/kernel/devices/pci.c#L123 (I guess it looks familiar to you)
06:47:51 <mquy90> I got 0x01 - AHCI 1.0
06:48:17 <mquy90> I am reading ahci to write driver, is it the right approach?
06:52:43 <bcos> mquy90: I think so, yes. Next step would be to add code to "pci_check_function()" that uses the info (vendor and device ID; then class code and subclass) to search for a driver that matches the info
06:53:08 <bcos> ..and load/start the driver if one matches
06:54:45 <mquy90> can you guide me? which resources to "search/load/start for a driver"
06:54:52 <mquy90> is it related to https://wiki.osdev.org/AHCI#Example_-_Read_hard_disk_sectors?
06:56:02 <doug16k> the PCI config has these fields to help you select a driver: vendor, device, class, subclass, programminginterface
06:56:19 <bcos> Imagine if you added an "if( (baseClass == PCI_STORAGE_DEVICE) && (subClass == PCI_SUBCLASS_AHCI) ) { // Start AHCI driver }" (after the similar code you have to deal with bridges)
06:56:30 <bcos> ..but
06:56:59 <bcos> ..then imagine it's more flexible - e.g. searched table/s or search the file system
06:57:06 <doug16k> for AHCI, you'd be looking for class = storage, subclass = SATA, PROGIF = AHCI
06:57:24 <bcos> Ah - yes
06:58:21 <mquy90> start ahci driver? can you explain a bit more
06:58:27 <mquy90> like what should I do?
06:58:35 <bcos> Mostly; you'd want a generic search pattern (most specific first, most generic last), and a generic way to find/start a driver that's found by that search
06:59:46 * bcos mostly cheats and just uses the info to construct file names, so (e.g.) for a device with vendorID=1234, deviceID=5678 I'd check for the file "sys/drv/pci/v1234d5678.drv"
07:00:14 <bcos> ..but, different people do different things
07:01:36 <mquy90> do you know how to do it via code example or osdev resource?
07:02:05 <bcos> Anyway; once you've found a suitable driver you'd want to tell it which resources it has to use (e.g. IO port range/s and memory mapped IO range/s that you got from the BARs). That way the driver doesn't need to care what type of bus the device is actually on
07:02:20 <bcos> (which is more useful for some things that others, but nice for future-proofing)
07:03:19 <bcos> I don't know if there's an example on osdev.org
07:03:57 <bcos> (most people just figure out how they want to do it and do it their own way, so...)
07:04:44 <bcos> Hrm
07:05:41 <bcos> mquy90: If I remember right you mostly only care about (eventually) getting file system/VFS working; and in that case there isn't really anything wrong with doing a temporary hard-coded thing (the "if( (baseClass...)" without generic support for any kind of device)
07:06:01 <bcos> *for any other kind of device
07:06:08 <mquy90> yup, I will hardcode first
07:06:42 <mquy90> to prove that I understand correctly
07:07:17 <bcos> There's
07:07:28 <bcos> Is it a monolithic kernel without support for "kernel modules"?
07:08:28 <mquy90> I have the proper pci device structure (ahci) is my disk, just don't know which way should I do next?
07:09:09 <mquy90> I would guess currently it is monolithic kernel
07:10:55 <bcos> Next would be something like "if( (baseClass == PCI_STORAGE_DEVICE) && (subClass == SATA) && (progInterface == AHCI) ) { start_AHCI_driver( getIRQ(bus, dev, fun), getBAR1(bus, dev, fun), getBAR2(bus, dev, fun),...);
07:11:41 <bcos> (assuming "monolithic with no support for modules")
07:12:22 <bcos> Later if/when you want "kernel modules" you'll have a "need to start a driver to access file system before I can start a driver to access file system" problem that you'll need to solve somehow (initial RAM disk)
07:12:32 <mquy90> do you know where I can read more to understand what should I do in start_AHCI_driver
07:13:52 <bcos> Shouldn't be too hard to find the AHCI spec
07:14:49 <mquy90> is it enough https://wiki.osdev.org/AHCI
07:15:25 <mquy90> I would prefer tutorials (osdev) over spec, spec seems to much for me
07:16:39 <bcos> It's better to get used to using specs. Tutorials (and osdev wiki pages) are mostly only intended for an introduction; and often they're written by people that are learning (and make mistakes) so you need to read the spec anyway
07:16:51 <ZombieChicken> might as well link this here https://news.ycombinator.com/item?id=18808984 <- Blue Book which covers the implementation of Smalltalk 80, in case anyone is intereste
07:18:15 <mquy90> I agree, I will read it later, but for the beginner like me, spec seems to much
07:18:35 <mquy90> usually, osdev tutorials have code examples so it is easier to understand haha
07:23:35 <glauxosdever> I'm considering doing a fun project after the exams (not osdev related, but something planned for my future OS anyway). An "image format abstraction layer", which allows each program using it to import/export every supported image format, where support for image formats can be added easily through a configuration file, provided there is an importer/exporter executable (could also be automated using a
07:23:41 <glauxosdever> command or a GUI). This configuration file would also specify exporting options for each format (and the program could simply use some defaults specified in the configuration file, or prompt the user to change them). Do you think it would be useful? Same for audio formats and video formats.
07:26:23 <glauxosdever> E.g. you want to use an obscure image format, you can add it to every program that uses this abstraction layer. Or experiment with a new image format (although I doubt GIMP will switch to my abstraction layer :p)
07:27:26 <glauxosdever> But as a concept, do you think it would be good?
07:30:44 <bcos> glauxosdever: In general, yes - seems like a good concept. In practice it'd depend on implementation details & environment
07:31:40 <bcos> (e.g. could just be a shared library with a standardised/abstract API, but then it wouldn't really be any different to what everyone does already)
07:31:53 <bauen1> another thing i would like to test at some point: integrating make into the filesystem, eg. tell the filesystem what files can be reproduced if needed (and doesn't have to be limited to make), combined with the command needed to recreate the file and a cost to create that could be used to reduce filesystem usage (and avoid backing up unecessary files), but that's just a dream of mine ....
07:32:33 <glauxosdever> bcos: True. It's different for Windows than for UNIX-like OSes
07:33:41 <bauen1> maybe i should get selfhosting first before experimenting with somewhat exotic (and not really performant) design ideas
07:34:08 <glauxosdever> But, maybe it would be already nice if I got it working on UNIX-like stuff
07:34:08 <bcos> For my OS design; I have the concept of "file format converters" built into the VFS; where processes say "open file X as format Y" and the VFS tries to find/run a service to automatically convert, and then caches the result to avoid "re-conversion" next time. The whole "make" nonsense would just be file format converters.
07:34:47 <bcos> (e.g. auto-convert source file into object file into executable, and cache it)
07:35:09 <bauen1> true
07:35:15 <glauxosdever> bcos: I remember your approach, but I still think it's too radical and, also, limited, unless you allow adding new conventers
07:35:57 <glauxosdever> Basically, not every format is suitable for everything
07:36:13 <bcos> It'd allow adding converters; but I only want "one way conversion" from old poop into my standard file formats with no way to convert back (mostly as a nasty way to lock people into my OS - not sure about the ethics of that)
07:36:15 <bcos> ;-)
07:36:40 <glauxosdever> Hm, I disagree with that :-)
07:37:36 <glauxosdever> Many different file formats have their own merits (it's just there isn't any standardised interface for all of them)
07:37:37 <bcos> It's a solution to the "too many standards! Let's create a standard standard! Oops, now there's even more standards(!)" problem
07:38:16 <glauxosdever> To be honest, I'd also like to work on better lossless audio compression (thus creating another standard)
07:38:20 <bcos> (mostly, there needs to be a formal process for deprecating old standards, and most systems don't have one, so there's far too many file formats for no sane reason)
07:39:42 <glauxosdever> Actually, I think people themselves deprecate old formats (e.g. .bmp)
07:40:03 <glauxosdever> (It would be also nice to deprecate .jpg :-)
07:40:48 <glauxosdever> But, in general, I agree there are too many file formats
07:41:23 <glauxosdever> E.g. C-header images (just why?)
07:42:09 <bauen1> i'm kind of interested in pushing the limits of make
07:42:15 <bauen1> eg. the entire system is in make
07:42:51 <bauen1> you changed a line in the C compiler source code ? make /usr/bin/cc and wait, make / to update everything
07:43:18 <bauen1> doing such shenanigans does have the problems of allowing you to "kill" the system
07:43:56 <glauxosdever> bauen1: Maybe limit "make /" to "make /home/bauen1/sysroot" or something like that
07:44:00 <zid> jpg is nice for what it's nice for
07:44:09 <zid> whoever at apple decided screenshots should be jpg should be shot in the face though
07:44:21 <bauen1> actually, my time might be better invested in writing a layer for below make, i.e. just outputs, dependencies and commands but i think that's what ninja is, isn't it
07:45:00 * glauxosdever dislikes lossy formats (but realises lossless may be infeasible for long HD videos)
07:45:20 <glauxosdever> So to return to the topic, what would you suggest for a file format abstraction layer?
07:45:22 <olsner> bauen1: sounds a bit like what you get managing the system with Nix (though that doesn't involve make, it does have a dependency tree of your root fs / system image)
07:45:48 <bauen1> yeah
07:45:59 <bauen1> it's on my list of things to try out, because in theory it sounds really awesome
07:47:12 <glauxosdever> I have two features I'd like to implement in it: 1) allow adding support for new file formats without rebuilding the abstraction layer and 2) allow format-aware programs and/or the user to specify exporting options
07:49:13 <glauxosdever> (I'm however talking about file formats of the same category, e.g. for images)
07:49:46 <glauxosdever> Maybe I'm being too crazy right now, I don't know. But I like this idea
07:51:49 <elderK> Hey all.
07:52:06 <elderK> I was wondering if anyone's hit a situation where stdint.h doesn't define u?intptr_t or the exact types.
07:52:49 <elderK> I find it interesting that uintmax_t is at least 64bits in length...
07:53:22 <elderK> uintptr_t being optional seems like an oversight, although I think I can understand why they didn't. Like, take IA32 with segmentation: You'd need a 48bit pointer, if you include the selector.
07:53:55 <elderK> Any other reasons you guys can think of why uintptr_t makes sense to be optional?
07:54:16 <elderK> I also thought that maybe some architecture has different lengths for pointers to different kinds of objects...
07:55:22 <glauxosdever> I can't think of any (not even the one you mentioned). At worst, they should say "the size of an uintptr_t variable and/or the meaning of its value is implementation defined"
07:56:23 <glauxosdever> Of course, segmentation still makes this stuff harder
07:58:22 <doug16k> elderK, it wasn't added until C99/C++11
07:58:51 <doug16k> maybe add -std option?
07:59:23 <glauxosdever> I don't know if anyone should be using C89 these days..
07:59:30 <doug16k> it is optional because the spec says it is optional
07:59:32 <zid> elderK: It's optional because C has been abandonware except for industrial interests since C89
07:59:42 <zid> which is why we got optional VLAs in C11, etc
08:05:27 <elderK> doug16k: Oh, I don't mean I don't have it defined. I'm more curious as to why they are optional :)
08:05:45 <elderK> zid: Aren't VLAs mandatory in C99?
08:06:03 <elderK> I never used VLAs anyway, so no loss there.
08:06:17 <elderK> The C I write is usually C89 with a few cherry picked features from C99. Namely, stdint.h :P
08:06:24 <elderK> And inttypes.h
08:14:02 <zid> Yea I use C89 if I can, and if I have to use C99 it's usually for named initializers or something
08:14:23 <elderK> There are some useful things that are in C99, like snprintf.
08:14:59 <elderK> I never really found named initializers all that useful. Then again, perhaps I am simply not imaginative enough :)
08:15:08 <elderK> I imagine they could be useful when initializing unions.
08:15:31 <zid> elderK: sparse arrays
08:16:10 <zid> char *tag[256] = { [0] = "Basic", [0x40] = "Extended", [0x80] = "Super", [0x81] = "Super Plus 1" };
08:16:20 <zid> or for structure fields, whatever
08:16:27 <zid> oh and compound literals are great
08:16:33 <zid> fucking love me a compound literal sometimes
08:19:46 <bauen1> c11 is kind of nice, since it actually standarises noreturn, static_assert and removes 'gets'
08:20:36 <elderK> zid: I wasn't aware of sparse array initializers. Now that *is* useful. I assume everything you don't specify is assigned zero?
08:20:43 <elderK> Compound literals sound useful too.
08:20:51 <zid> yes, 0 as if by assignment
08:21:22 <zid> same as if you do T blah = {1, 2, 3};
08:21:35 <zid> where blah has >3 members
08:24:30 <elderK> Now if only you could say "I want this to be the default initializer instead of zero"
08:24:37 <elderK> Of course, assuming C, not C++
08:30:46 <doug16k> :)
08:31:09 <zid> You can, you type it
08:31:20 <elderK> :P I know
08:31:28 <elderK> I was just meaning it would be a handy shorthand otherwise.
08:32:11 <doug16k> they are optional because it isn't required for it to make any sense on a given architecture to treat a pointer like an integer, and there is a limit to how far a compiler has to bend over backward to see a pointer as an integer
08:33:07 <doug16k> the intent is to allow C compilers to exist for the most obscure memory model imaginable
08:34:18 <doug16k> pointers can be strange abominations that are doing untold things to work
08:34:44 <zid> including lovely things like different bit-widths for each type and your null pointer constant being 7 :P
08:35:38 <elderK> Yeah, that's what I thought.
08:35:56 <elderK> Or say, tagged pointer systems, where the tags are meant to be completely hidden. Or something.
08:36:08 <elderK> I'd be interested in reading about a system with bizarre pointers.
08:36:09 <elderK> :D
08:36:16 <zid> but, 'by assignment by 0' means mov blah, 7
08:36:26 <zid> because that's what null pointer constant semantics are
08:36:43 <zid> it's why memcpy(somestruct_with_pointers, 0, sizeof(somestruct)); is bad
08:36:48 <zid> you want the = 0; semantics
08:36:53 <zid> not 'set all bytes to 0' semantics
08:37:03 <elderK> Excellent point
08:37:04 <doug16k> 16-bit protected mode code would be weird like that. the selector is arbitrary, and there is a 16 bit offset
08:37:23 <doug16k> you can't "carry" into the selector when offset goes > 64KB
08:37:26 <elderK> 32bit segmented too, right? selector, offset.
08:37:56 <doug16k> yes if not flat model
08:38:09 <elderK> Anything weirder? :D
08:38:15 <doug16k> harvard arch
08:38:25 <doug16k> where it is literally impossible to read code byte through a data pointer
08:38:26 <elderK> Different spaces for code and data?
08:38:44 <doug16k> try casting a function pointer to a void pointer on that
08:39:15 <doug16k> function pointer and data pointer are not compatible at all
08:39:22 <zid> legal in C (but you can't dereference it in C so it doesn't matter)
08:39:47 <zid> As long as you put it back again before you try to call it it's pretty kind to you
08:39:50 <doug16k> any architecture with bank switching would apply
08:39:50 <elderK> Is that due to potential sizes of those address spaces being different, or is it just more of a "you literally can't address code as data."
08:39:59 <elderK> Good point: The pointer would need to know the bank
08:40:07 <doug16k> if you had EMM memory bank switching in old DOS code
08:40:09 <doug16k> ya
08:40:31 <doug16k> a compiler could make it transparent if it tried
08:40:33 <elderK> Like, you'd expect if you had an fnptr, cast to void *, then back to fnptr, it would be valid. But that casting that void* to say, int* and dereferencing would simply be "undefined."
08:40:57 <elderK> Or say, casting some data pointer to an fnptr, also undefined.
08:41:11 <doug16k> yes. but you could show it "works" on many architectures
08:41:57 <doug16k> a kernel is so utterly platform dependent that it doesn't make a whole lot of sense for all of that to be completely platform agnostic. let platform specific things be platform specific
08:42:00 <elderK> I See. I wonder if a C compiler targeting Harvard would just make it "undefined" to use it wrong, or outright generate a compile time error.
08:42:12 <elderK> Aye.
08:43:25 <elderK> So, for your own kernels, do you use stdint?
08:43:28 <elderK> Or define your own stuff?
08:43:33 <doug16k> definitely stdint
08:44:03 <elderK> Same here.
08:44:16 <elderK> I guess you'd have to come up with some workaround if you know, some platform's stdint didn't define stuff you use.
08:44:18 <doug16k> in my kernel code I have a helper include that does what it has to do to make stdint types exist
08:44:21 <elderK> Like, do you use uintptr_t? :)
08:44:26 <zid> consider segmentation, if you want an easy example of a setup where code and data pointers might never overlap
08:44:28 <doug16k> yes
08:44:44 <elderK> I'd be interested in seeing that helper.
08:46:00 <doug16k> https://github.com/doug65536/dgos/blob/master/kernel/arch/x86_64/types.h
08:46:20 <doug16k> you won't see anything new in there
08:47:55 <doug16k> __SIZE_TYPE__ is useful
08:49:03 * eryjus makes a mental note to review doug16k's example
08:49:13 <doug16k> I should probably add inttypes.h there
08:50:18 <elderK> Why do you have the guard for _cplusplus?
08:50:23 <elderK> There's a lot of C++ stuff there not covered by that?
08:51:26 <doug16k> yes the countof implementation should select the define for not __cplusplus
08:51:37 <doug16k> thanks. I guess that proves nothing includes it in C, yet
08:51:54 <elderK> NP. The namespace things should be guarded to, no?
08:51:59 <elderK> *too
08:52:14 <doug16k> I think I'll let C code trying to use namespaces error out
08:52:52 <doug16k> won't hurt to preprocessor define
08:52:59 * elderK nods
08:53:04 <doug16k> I suppose I could just leave them undefined, cleaner
08:54:01 <elderK> Reminds me of a discussion I had with a classmate of mine. He's super into like, kill any legacy. So, to him, WORD and DWORD and stuff in Win32 should have all been replaced, because it's ungodly legacy. My argument was that it would amount to a cosmetic change that would break zillions of things, for no real gain.
08:54:40 <elderK> It's funny, when I was younger, I was the same. But these days, I kind of appreciate legacy stuff. If only because I found a lot of it is simpler to program. Say, serial ports vs. USB or whatever.
08:54:40 <zid> DWORD and WORD don't mean anything anyway
08:54:44 <elderK> There's something to be said for simple, reliable, stuff.
08:55:17 <elderK> zid: They don't? I was of the impression that they were 32bit and 16bit quantities, respectively. Even on 64bit architectures.
08:55:38 <zid> maybe, maybe not
08:55:47 <zid> word on arm tends to mean 32bit
08:55:49 <doug16k> a word was 16 bits on a 286
08:56:25 <doug16k> which was the original target for windows
08:56:29 <zid> addiuw or whatever ppc/arm/whatever all mean 32bit
08:56:30 <olsner> in Win32 they mean what they mean there, in the real world it of course depends on how big a word is
08:56:40 <zid> which makes them meaningless
08:56:51 <elderK> Yup. Shows how much I know: I thought the sizes would have been standardized to mean the same thing regardless of architecture. Like, sure, a word might be 32bit on some platform, but Win32 would still define WORD as a 16bit quantity.
08:56:53 <zid> because either they're WINDOWS_32BIT_TYPE and you just memorize it and it isn't legacy
08:57:02 <zid> or they mean random things, and it's still not legacy, because it's dynamic
08:57:26 <elderK> I.e. I am considering the technical term "word" to be distinct from Win32 WORD.
08:57:30 <zid> even funnier imo is that it mixes DWORD and ULONG
08:57:43 <Kazinsal> words are 36 bits, bytes are 6. *crosses arms*
08:57:57 <elderK> With the understanding that the technical term "word" really means the native length on some arch.
08:58:09 <doug16k> a byte is the smallest addressable unit of storage. a word is the size that you like to access
08:58:19 <zid> Kazinsal: only if long words are 48
08:58:22 <zid> and long floats are 80
08:58:24 <elderK> What about systems that are not byte addressable? :P
08:58:33 <doug16k> then a byte is whatever number of bits
08:58:36 <zid> elderK: CHAR_BIT becomes 16 :P
08:58:46 <elderK> zid: Or more, even.
08:58:50 <elderK> Although they'd probably be packed.
08:58:51 <zid> 18 then
08:58:55 <zid> I don't care
08:59:11 <zid> C specifies things in terms of numbers of CHAR_BIT chars, POSIX mandates it to be 8 though
08:59:57 <zid> no posix on your dsp :(
08:59:58 <elderK> :P Then there are paragraphs, which I believe are 16 words?
09:00:08 <zid> is that a dos segmentation term?
09:00:17 <elderK> Paragraph? I guess so.
09:00:21 <doug16k> DOS people use paragraph to mean 16 bytes (increment segment)
09:00:28 <zid> yea exactly what I was thinking
09:00:32 <zid> segment++ is 16 bytes
09:00:41 <elderK> Thanks :) I misremembered.
09:00:46 <elderK> And that makes a weird kind of sense :)
09:01:23 <doug16k> boot metaphor messes up a bit at cache "line", but goes back to sensible at "page"
09:01:32 <elderK> I love stdint.h. It's extremely rare for me to write code that doesn't use the types it defines.
09:01:39 <doug16k> s/boot/book/
09:01:49 <elderK> Except in a rare case where it's like "Native length."
09:02:25 <elderK> Then again, wouldn't the uint_fast_ types be the native length?
09:02:51 <doug16k> the whole point is not knowing
09:02:55 <zid> no, they're the fast type at least that wide
09:03:06 <zid> which is just going to be 32bit on almost every platform
09:03:16 <doug16k> for mental image, _fast_ will be 64 bit on x86_64
09:03:21 <elderK> Agreed. But, I just mean sometimes you need to be able to refer to the native length, in a portable way :P
09:03:35 <zid> doug16k: afaik fast differs between msvc and gcc on that front, but I may be making that up
09:03:41 <doug16k> I mean gcc
09:03:59 <doug16k> big differences there between vc and gcc though ya
09:04:32 <doug16k> long isn't 64 bits on x86_64
09:04:39 <doug16k> in windows*
09:04:56 <zid> ILLLLPPPPPPP128
09:04:57 <doug16k> right there is a gigantic difference. it is 64 bit on gcc
09:05:30 <elderK> Aye. LP64 vs LLP64, right?
09:06:14 <doug16k> right
09:07:36 <doug16k> I use their names to remember. for "LP" I remember "Long is Pointer sized" and for "LLP" I remember "long long is pointer sized"
09:12:38 <doug16k> how silly is it for "int" and "long" to be the same, so you then need "long long" to specify something bigger
09:12:50 <doug16k> LP64 is way more sensible
09:14:27 <doug16k> what's next? apparently microsoft would have named SSE long long long, and AVX would be long long long long, and AVX-512 would be long long long long long
09:14:47 <elderK> :P Thank god for stdint :P
09:15:12 <elderK> I remember 16bit compilers where short and int were the same length.
09:15:16 <elderK> IIRC.
09:15:21 <doug16k> yes
09:15:32 <doug16k> no room between 2 and 1 byte (char)
09:15:56 <doug16k> kind of had no choice
09:18:10 <ZombieChicken> just wait. iirc, i think there is a RISC-V that might support 128-bit, so suddenly your int and your long long long int will be the same size (or something like that)
09:20:29 <doug16k> x86_64 has __int128
09:20:55 <doug16k> half assed implementation anyway
09:21:13 <doug16k> (can't put a 128 bit literal in code, otherwise is ok)
09:22:37 <doug16k> `__int128 x = 0x12345678123456781234567812345678;` is a syntax error
09:23:46 <doug16k> have to say x = 0x1234567812345648; /* upper part */ x <<= 64; x |= 0x1234567812345678; /* lower part */
09:24:34 <zid> Fun thing: WHen do you need U / UL on constants in C?
09:24:34 <elderK> I wonder why they did htat.
09:24:49 <zid> whenever sometone tries to compile your code on something with a stupid sized int :P
09:24:55 <elderK> zid: Whenever you need to ensure something is that type, promotions and stuff.
09:25:00 <zid> nope
09:25:04 <doug16k> elderK, probably so they wouldn't have 128 bit types propagate throughout all of the compiler data structures
09:25:12 <zid> unless you intend to write 0x12345UL every single time?
09:25:32 <elderK> zid: I would mean for when the promotion rules would treat something as int, rather than unsigned int.
09:25:41 <zid> constants are int
09:25:42 <elderK> Or when that would actually matter.
09:25:49 <zid> so if you want them >16bit you need to UL them
09:25:53 <zid> which is pretty silly
09:25:57 <doug16k> elderK, unsigned wins
09:26:30 <elderK> Okay, so when should you use U and stuff?
09:26:41 <elderK> You mentioned weird integer sizes.
09:26:46 <doug16k> but, if it is negative, it will sign extend to the needed width, then become unsigned
09:27:23 <doug16k> U when you don't want sign extension
09:28:20 <elderK> :| I still find it difficult to know when I need to cast something to a larger type, you know, to ensure stuff is sane wrt promotion and conversion and stuf.
09:28:44 <zid> elderK: because signed types are evil :P
09:28:54 <doug16k> usually you don't need to enlarge. the other operand will enlarge it for you
09:29:00 <zid> (and you almost never see L by itself so it may have been confusing)
09:29:13 <zid> except it needs to have the right width *before* the conversion not to truncate
09:29:18 <elderK> Like say, whatever = something | something | something_else << 31
09:29:25 <zid> you can't do long = int; and expect it to have full range
09:29:33 <elderK> whatever is some unsigned type, all the somethings are just constants, same with something_else
09:30:04 <zid> so technically all those times you do like uintptr = 2MB; wouldn't get you a lovely fat 0 on anything where int is 16bit (hopefully with a warning at least)
09:30:05 <doug16k> elderK, it will automagically be wide enough for the or operations to work
09:30:05 <elderK> Ignore that example, it makes no sense. But, you get what I mean.
09:30:23 <zid> also stupid: C allows the implementation to define NULL as 0 instead of (void *)0
09:30:38 <zid> which means printf("%p", NULL) is UB
09:30:43 <doug16k> geordi, --precedence whatever = something | something | something_else << 31
09:30:43 <geordi> whatever = ((something | something) | (something_else << 31))
09:30:46 <zid> because %p expects void * and you passed an int
09:31:44 <doug16k> elderK, this would work: whatever = something | something | (uint64_t(something_else) << 31)
09:32:05 <zid> That's C++ :P
09:32:09 <doug16k> those 'something' will promote to same as the somethong else
09:32:14 <doug16k> you know what I mean
09:32:18 <doug16k> lol
09:32:38 <elderK> Right, but if you don't use the cast, and if something else is a constant, wouldn't the result be some integer, and then that would be converted to whatever you'd assign it to?
09:33:02 <doug16k> it will be int or the type of something_else, whatever is larger
09:33:07 <zid> elderK: 1<<31 the left hand side is int
09:33:09 <zid> so it's an int
09:33:24 <elderK> Right, so it'd wind up some massive negative value.
09:33:31 <zid> or 0
09:33:33 <zid> if int is 16bit
09:33:51 <elderK> Also, another question: enums vs #define
09:34:05 <elderK> AFAIK, enums are int, right?
09:34:10 <zid> if enums were proper types they'd great
09:34:12 <zid> but they're not
09:34:20 <zid> at most they gain you a couple of warnings relating to switches
09:34:30 <doug16k> in C++ you can specify underlying type
09:34:34 <elderK> Yup, but speaking C here.
09:34:41 <zid> but enum F f = ENUM_G_VALUE; is perfectly valid, sadly
09:34:49 <zid> if that was a type issue I'd be so happy
09:35:03 <elderK> It is for enum class on C++, is it not?
09:35:11 <zid> I do like int f(enum BRUSHES b){} or whatever
09:35:20 <zid> but you can just pass an enum POTATO and there's no warning
09:35:40 <zid> all you really gain is switches warning you you forgot a case
09:36:24 <elderK> Aye. And also being able to see the enumerants in the debugger, right?
09:36:37 <zid> oh yea possibly
09:36:40 <zid> never tried
09:37:12 <elderK> I've never hit a case where the enum-being-int is a problem, but that's probably chance.
09:37:15 <elderK> :P
09:37:26 <zid> enum isn't int, it just has the same storage as it
09:37:35 <zid> which is never a problem in practice, who has more than 64k enum members
09:37:42 <zid> but it's annoying in IDA
09:37:58 <zid> because I RE a lot of code that assigns enum members to shorts, and I can't tell it the type is a 'short enum' :P
09:38:11 <elderK> Well, I was meaning you might have an enumerant for bit flags, say. And you might have flags that are larger than would fit in a 16bit int, or a 32bit int, or whatever.
09:38:55 <zid> possible, but you just use define in that case, there's no type safety on enum anyway
09:39:02 <zid> so it's not like it matters, if it had it it might though
09:39:17 <zid> because then "You only get type safety if your enum values fit inside ints" would be a thing
09:40:01 <elderK> I kind of like how enumerations are kind of self documenting in a silly way. Like, by virtue of being an enumerant of some enumeration, you know that these symbols are related, and how.
09:40:11 <elderK> Where as with #defines, you need to provide such documentation yourself.
09:40:25 <elderK> Also, the automatic numbering is handy with enumerations.
09:40:53 <zid> except you don't get the 'belongs to' on a type level
09:40:56 <zid> so in practice it's useless
09:41:06 <zid> might as well just look at a #define list and see where the linebreaks are
09:41:23 <zid> There's so much trivial shit like this they could have fixed for C99 and didnt it's super sad
09:41:37 <elderK> Aye, agreed. I just find it useful, in any case.
09:42:39 <elderK> It's the same thing for me with regards to using signed or unsigned types, and always pick the one that matches the intention of whatever I'm doing. If this value is never intended to be negative, I'll use unsigned and that, to me, serves as a form of documentation.
09:42:54 <elderK> Although granted, you do get nice warnings nowadays if you misuse an unsigned type.
09:42:55 <zid> well.. yea
09:42:56 <zid> I should hope so lol
09:43:16 <elderK> But that's my rationale for enums, mostly. Sure, they aren't type-safe. But they do give some basic documentation to the reader.
09:43:21 <elderK> YMMV. :)
09:43:51 <doug16k> you could case an enum to std::underlying_type<my_enum> and it will do the right thing
09:43:59 <doug16k> ::type*
09:44:28 <elderK> I'm glad C++ has that stuff now. It was such a PITA in the past when you had to define operators | and stuff for enumerations.
09:44:36 <elderK> Then again, I've been told you really shouldn't use enumerations for "Flags" anyway.
09:44:41 <elderK> Which is generally what I use them as :P
09:44:55 <doug16k> elderK, note that anything that wraps around must be unsigned too, unless you want the optimizer to make a mess of it
09:44:56 <elderK> I'll have to switch back to #define in these cases, I think.
09:45:07 <elderK> Good point, doug :)
09:52:59 <doug16k> I finished adding timeouts to my condition variable waits. implemented chrono to support time_point wait_until. it's zero cost to convert a time_point<int64_t,chrono::nano> to int64_t nanotime timeout time point
09:54:43 <doug16k> got to dust off some elementary school fraction arithmetic and use it for once :P
09:55:22 <doug16k> you can compute a gcd for a fraction at compile time in C++ and reduce it to lowest terms
09:59:00 <doug16k> converting milliseconds to nanoseconds, you'd have a value with ratio 1:1000, and you want 1:1000000000, so you inverse the old ratio, multiply new ratio by old ratio: 1000000000:1 * 1:1000 == 1000000000:1000. gcd is 1000, divide both, 1000000:1, so you take millisecond count multiply by 1000000 and divide by 1
09:59:43 <doug16k> all at compile time except the multiply and divide at the end
10:05:30 <doug16k> neat thing is, chrono time_points are so small that they fit in a register, so you are really just passing the one member of time_point in a register as is. doesn't get much closer to zero cost than that. normally the ratio is nanoseconds and that is already the unit I want, no conversion, just take the integral value
10:07:24 <doug16k> if I did std::chrono::steady_clock::now() + std::chrono::seconds(4) it would magically compute now plus 4 billion nanoseconds
10:24:06 <pterp> I'm redoing my tasking based off of brendans tuorial on the wiki, and i'm having the strangest problem. Whenever a task calls yield and the next task yield back to that task (it's two tasks in a yield loop), the address it returns to in the original task is the one right after the call instruction that started the function that called yield. Here's the tasking code. switch_to_task is the only external function, and it's brendan's switch
10:24:07 <pterp> all the addresses filled in. https://pastebin.com/36DFfx3s
10:42:31 <doug16k> yield spamming isn't multithreading. the main case for threads is waiting for something
10:42:41 <doug16k> threads wait more than they run on average
10:43:02 <doug16k> and most programs wait always, with blips of microseconds of input processing here and there
10:43:27 <doug16k> you need to make a way to make a thread not runnable asap
10:43:44 <pterp> I only have two tasks. "Init", which is just a program the kernel loads from initrd, and the kernel task, which starts init. The yield loop is intentional as a way to test yield.
10:44:27 <doug16k> ok I was afraid your synchronization mechanisms were poll and yield loops
10:45:34 <pterp> This is VERY early in os dev. There's no sync.
10:45:50 <pterp> Anways, aly idea what the problem might be?
10:45:52 <pterp> *any
10:47:22 <pterp> This is the code the kernel is running after loading and creating the init task: yield();
10:47:22 <pterp> vga_write_string("KYIELD");
10:47:23 <pterp> yield();
10:47:25 <pterp> Init's code:
10:47:33 <elderK> You guys have reminded me of a question I've had for awhile :P In a microkernel, how do you control which programs can be drivers, and which can't? Do you even make a distinction between those that can and cannot?
10:47:54 <doug16k> pterp, that code won't work. there is no synchronization mechanism protecting that task list
10:48:08 <pterp> Syncronization?
10:48:14 <doug16k> it can change out from under it at any moment right?
10:48:42 <doug16k> I am not saying "here's your bug, do that and press run and it is fine"
10:49:01 <jjuran> elderK: I'd imagine being a driver requires access to certain memory ranges. If you have the I/O access you need, you can be a driver.
10:49:31 <elderK> jjuran: Right. But any process can ask for access to those ranges or IO ports.
10:50:02 <doug16k> elderK, heavily privileged only of course
10:50:29 <doug16k> you could take it to the extreme and hardware enforce it with IOMMU
10:50:33 <pterp> elderK: Right now i have the concept of "privleged" programs. This doesn't mean kernelmode, but rather full page table control and io port acess. Init starts out as the only privleged progrms, and if a program is privleged, it's child programs are too. Wwhen init starts a non-priveleged program, before calling exec(), it requests to lose its privleges.
10:50:41 <elderK> Right, but how to go about that? Only a "superuser" program can do that? Only programs possessing certain capabilities? If so, how is the process bestowed those capabilities?
10:50:59 <elderK> pterp: Right, how do you know what is privileged and what is not?
10:51:35 <elderK> Like, it's one thing to be privileged, then downgrade. But how do you store that privileged-ness in a safe way?
10:51:51 <pterp> One flag in the task structure.
10:51:59 <elderK> Sure. But when you load the binary from disk?
10:52:00 <elderK> etc.
10:52:02 <doug16k> you make it know
10:52:12 <doug16k> how long is a piece of string?
10:52:33 <elderK> Aye. I just wonder about the different way of marking said privileged programs. :)
10:52:44 <doug16k> one way they know in practice is extended attributes in the executable metadata
10:53:17 <doug16k> i.e. you can grant it super privileges by adding some magic attribute to the executable
10:54:24 <elderK> Right. Then you need some way to ensure people can't set that attribute ordinarily.
10:54:27 <doug16k> the loader can check for that attribute, and if it is not there, take away the ability for this process to have that capability forever
10:54:51 <doug16k> it must be utterly impossible to turn it back on
10:54:53 <pterp> "Marking" is done by having a "request privleges" as the first line in main(). If it has privleges already, the call does nothing. If it doesn't have privleges, the kernel sends a request to all logged-in terminals, and then when a terminal responds (either ok or t), it allows privleges or not.
10:54:58 <pterp> *ok or not
10:55:50 <elderK> That sounds kind of painful.
10:56:02 <pterp> It's the most secure,
10:56:11 <pterp> *that i can think of
10:56:14 <elderK> Only as long as people don't just say YYYYYYYYYYYYY
10:56:15 <elderK> :P
10:56:22 <elderK> Which practice shows, they will and do.
10:56:33 <pterp> you have to trust the users. Maybe all root terminals?
10:56:53 <pterp> (which would include commands run wih sudo)
10:57:11 <pterp> if you cant trust the syadmin. there's a bigger problem.
10:58:22 <elderK> Seems like cryptography would be useful.
10:58:59 <doug16k> the attacker can modify the metadata? they can replace executable code with their own it sounds like
10:59:22 <doug16k> if they can rm the program and cp a new one there, security is a waste of time to talk about
10:59:38 <elderK> Programs could have a list of capabilities that they require, that list would be encrypted using some private key, the kernel would have the public key. It'd be signed in another way too, so that you can verify the process is not altered.
10:59:39 <elderK> Then maybe have some other part, which administrators can alter: To add capabilities to programs. As with before, signing and stuff to make sure people can't just hexedit the program
11:00:45 <elderK> But yeah, generally, you can't stop someone from bestowing stuff to "HAPPYKITTEN.EXE" which subsequently causes mayhem.
11:00:50 <doug16k> not having w permission is enough isn't it?
11:01:01 <jjuran> Executables shouldn't have privileges unless they're in privileged locations only writable by sysadmins.
11:01:28 <elderK> doug16k: As long as any modification a user can make, isn't valid, yeah.
11:01:39 <jjuran> /Processes/ can be granted privileges by other means.
11:02:38 <elderK> Yes, but that still requires a way to know which privileges to restore. Even if you have some master program that is responsible for giving stuff privileges, you still need to be able to restore that from shutdown. So, there needs to be some way to know privileges a program should have.
11:02:39 <elderK> That's where making sure you can't just hexedit in some new privileges come in, however those privileges are stored.
11:02:46 <doug16k> you want "can't modify it because it is computationally infeasible to change the metadata without breaking the signature"... my version is "can't modify it"
11:03:23 <elderK> Well, sure. Your system can make sure no one can write that stuff. But I mean, you want to stop someone taking the HDD, messing with it on another system that doesn't care.
11:04:03 <elderK> So, "you can't write this on my system" isn't safe enough. What's to stop you from hex editing the disk on another machine?
11:04:07 <doug16k> can't they nop out the signature check in that other system?
11:04:41 <elderK> Let's say they try to hex-edit out the part of the kernel that ensures that is done, or the loader, or however you load processes. Assume that is signed.
11:04:49 <elderK> So any modification someone makes, will invalidate that.
11:05:26 <doug16k> which is why there is no "combat techniques for after you have been impaled by 10 spears and shot by 10 assault rifles", too late by then
11:05:27 <jjuran> "elderK: What's to stop you from hex editing the disk on another machine?" <— Lack of physical access?
11:05:47 <elderK> jjuran: Sure. But you can't assume that will be true for all systems.
11:06:02 <jjuran> Physical access is game over.
11:06:51 <elderK> It's like arguing a lock is useless, because you can pick it. But it serves another purpose: Slow down the invader for such a length of time, such that someone is bound to see them lockpicking :P
11:07:16 <elderK> You are right, if someone gets total access to the machine, and can do what they want with it, it's game over, for the most part.
11:07:23 <elderK> They could always have an ICE and change how the program was executing
11:07:42 <jjuran> More secure than a lock is no door at all.
11:08:15 <doug16k> I think the point is, you have to realize where it is game over and focus on doing something in scenarios where you can actually do something
11:08:16 <elderK> Sure. Still, I've been curious about how you guys handle this kind of stuff :)
11:09:05 <doug16k> where the attacker has no physical access is a good start
11:09:49 <doug16k> if you want to do physical access, then you full disk encrypt it
11:09:57 <doug16k> you offload the problem to whatever device knows the key
11:10:38 <elderK> Aye. Full disk encryption would seem to be a must.
11:10:55 <elderK> That and not assigning privileges to things based on their filename :P For obvious reasons.
11:11:00 <elderK> Interesting to think about :)
11:12:10 <doug16k> they presumably make it unreasonably hard by comically high orders of magnitude
11:14:14 <Kazinsal> Door fitment is critical. No need to spend time trying to pick a lock or duplicate RFID credentials if you can just slide a little metal hook through a gap between the door and the frame and grab the latch
11:14:28 <elderK> True
11:14:57 <doug16k> you could ask a passerby to open it for you
11:15:03 <doug16k> they probably will
11:16:14 * geist passes by
11:16:52 <doug16k> they will check your costume, looks right, there you go, they hold the door for you as they say "I forget my card sometimes too"
11:17:48 * pterp still wants help on my problem
11:18:29 <jjuran> Kazinsal: Or reach through the iron bars and unlock it as if from the other side. :-)
11:22:56 <elderK> Another question is how do allow programs to define new types of capabilities? Does the kernel just provide some way of generating "an unforgeable" token, and each program that defines a new capability, is responsible for tracking what they mean? Like say a FS server. The kernel will create unforgable capabilities, but the FS server is the one that actually implements the "methods" of that capability.
11:23:19 <elderK> Or does the kernel track information that tells it which process to call when something else tries to invoke it?
11:23:22 <pterp> Breif remider on my problem: I have two tasks. When the first task yields to the second, and then the second yields back, the return address is the instruction after the call instruction that called the function that called yield
11:26:25 <pterp> i'm following brendan's multitasking tutorial BTW.
11:30:56 <zid> also known as the return address, btw
11:32:42 <pterp> in that sentence, return addres meant "the address that the task stated ececuting from after getting yielded to, unwinding the interrupt stack, and executing an iret"
11:32:57 <pterp> *started excecuting from
11:33:02 <zid> the instruction after the call, is the return address
11:33:08 <pterp> *executing from
11:33:14 <zid> if it was the address *of* the call it'd be an infinite loop :P
11:33:32 <pterp> yes. I misused return address in away that gets confusing.
11:33:47 <zid> I was more complaining that you didn't use it
11:34:02 <pterp> true.
11:34:59 <pterp> Any ideas what might be causing it? Here's the tasking code:https://pastebin.com/36DFfx3s. switch_to_task is the one in the brendan multitasking tutorial, but with addresses filled in.
11:47:55 <pterp> Hello?
11:47:59 <pterp> Any ideas?
11:51:35 <eryjus> pterp, I'm looking at your code, but I do not understand what the question is
11:52:15 <pterp> Why is that happening? It should go to the vga_write_string("KYIELD") right after thje yield() call.
11:52:43 <pterp> The kernel codeafter loading and ceating the init task: yield();
11:52:43 <pterp> vga_write_string("KYIELD");
11:52:44 <pterp> yield();
11:53:06 * pterp Init code after initilzing it's VGA driver: vga_write_string("INIT VGA\n");
11:53:06 * pterp yield();
11:53:08 * pterp for(;;) {
11:53:09 * pterp vga_write_string(" INYIELD");
11:53:09 * pterp }
11:55:42 <eryjus> Sorry, I'm going to ask for a well formed description of the problem you are referring to. Don't paste code, but describe the behavior you are seeing and if it is not clear, why it is wrong. I used the same tutorial to rework my scheduler recently, so I am familiar, but I am not following what you are asking about.
11:57:42 <pterp> Problem: I have two tasks. I have given the applicable code, so i will be referring by line number. Here's what should happen. Kernel line 1->init line 1->init line 2->Kernel line 2->continue. Here's what happens: Kernel line 1->init line 1->init line 2->return address of kernel function, which is a jmp to itself.
11:58:18 <pterp> "Kernel" reffers to a task with no user mappings and just runs kernel space code. Not any code for syscalls or the like.
11:58:36 <eryjus> line 1 reads: #include "tasking_helpers.h"....??
11:59:19 <pterp> lines are the "kernel code" i posted recently and the "init code" i also posed recently. See a few posts back.